summaryrefslogtreecommitdiff
path: root/mysys/my_delete.c
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2019-02-21 14:40:52 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2019-02-21 14:40:52 +0100
commit93ac7ae70ff000353538f732899b421a3f2ea7ce (patch)
tree819b5ca057d80b42699de219c982b7924857c406 /mysys/my_delete.c
parent4932aba921755cfbc351b92c67068a5c48d3922b (diff)
parenta40de1bdeb218d66d5cc737758a4bab1b06f255d (diff)
downloadmariadb-git-93ac7ae70ff000353538f732899b421a3f2ea7ce.tar.gz
Merge branch '10.3' into 10.4
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 cba24f90565..044c55d8fb1 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
@@ -158,3 +159,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;
+}
+
+