summaryrefslogtreecommitdiff
path: root/mysys/my_delete.c
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-02-19 17:41:13 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-02-19 17:41:13 +0200
commitfc124778ea4e3d0d6bc35d816b367d0ed470bf0c (patch)
treeb5e694a4c6c7a73494762d7f54c9114e14c9098e /mysys/my_delete.c
parenta4cd91c526933e87d78a4a3fec66a074616f3c32 (diff)
parent88b6dc4db5567951f9c0d0baa6e965d44a7130b1 (diff)
downloadmariadb-git-fc124778ea4e3d0d6bc35d816b367d0ed470bf0c.tar.gz
Merge 10.2 into 10.3
Diffstat (limited to 'mysys/my_delete.c')
-rw-r--r--mysys/my_delete.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index beece473a01..c7023b61df0 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -18,6 +18,7 @@
#include <my_sys.h>
#ifdef _WIN32
+#include <direct.h> /* rmdir */
static int my_win_unlink(const char *name);
#endif
@@ -160,3 +161,63 @@ error:
DBUG_RETURN(-1);
}
#endif
+
+/*
+ Remove directory recursively.
+*/
+int my_rmtree(const char *dir, myf MyFlags)
+{
+ char path[FN_REFLEN];
+ char sep[] = { FN_LIBCHAR, 0 };
+ int err = 0;
+ uint i;
+
+ MY_DIR *dir_info = my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT));
+ if (!dir_info)
+ return 1;
+
+ for (i = 0; i < dir_info->number_of_files; i++)
+ {
+ FILEINFO *file = dir_info->dir_entry + i;
+ /* Skip "." and ".." */
+ if (!strcmp(file->name, ".") || !strcmp(file->name, ".."))
+ continue;
+
+ strxnmov(path, sizeof(path), dir, sep, file->name, NULL);
+
+ if (!MY_S_ISDIR(file->mystat->st_mode))
+ {
+ err = my_delete(path, MyFlags);
+#ifdef _WIN32
+ /*
+ On Windows, check and possible reset readonly attribute.
+ my_delete(), or DeleteFile does not remove theses files.
+ */
+ if (err)
+ {
+ DWORD attr = GetFileAttributes(path);
+ if (attr != INVALID_FILE_ATTRIBUTES &&
+ (attr & FILE_ATTRIBUTE_READONLY))
+ {
+ SetFileAttributes(path, attr &~FILE_ATTRIBUTE_READONLY);
+ err = my_delete(path, MyFlags);
+ }
+ }
+#endif
+ }
+ else
+ err = my_rmtree(path, MyFlags);
+
+ if (err)
+ break;
+ }
+
+ my_dirend(dir_info);
+
+ if (!err)
+ err = rmdir(dir);
+
+ return err;
+}
+
+