diff options
Diffstat (limited to 'src/stdlib/paths.c')
| -rw-r--r-- | src/stdlib/paths.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/stdlib/paths.c b/src/stdlib/paths.c index c7743759..9ecf891b 100644 --- a/src/stdlib/paths.c +++ b/src/stdlib/paths.c @@ -2,6 +2,7 @@ #include <dirent.h> #include <errno.h> #include <fcntl.h> +#include <ftw.h> #include <gc.h> #include <glob.h> #include <grp.h> @@ -408,6 +409,27 @@ public void Path$set_owner(Path_t path, OptionalText_t owner, OptionalText_t gro fail("Could not set owner!"); } +static int _remove_files(const char *path, const struct stat *sbuf, int type, struct FTW *ftwb) +{ + (void)sbuf, (void)ftwb; + switch (type) { + case FTW_F: case FTW_SL: case FTW_SLN: + if (remove(path) < 0) { + fail("Could not remove file: %s (%s)", path, strerror(errno)); + return -1; + } + return 0; + case FTW_DP: + if (rmdir(path) != 0) + fail("Could not remove directory: %s (%s)", path, strerror(errno)); + return 0; + default: + printf("Type: %d\n", type); + fail("Could not remove path: %s (not a file or directory)", path, strerror(errno)); + return -1; + } +} + public void Path$remove(Path_t path, bool ignore_missing) { path = Path$expand_home(path); @@ -422,10 +444,10 @@ public void Path$remove(Path_t path, bool ignore_missing) if (unlink(path_str) != 0 && !ignore_missing) fail("Could not remove file: %s (%s)", path_str, strerror(errno)); } else if ((sb.st_mode & S_IFMT) == S_IFDIR) { - if (rmdir(path_str) != 0 && !ignore_missing) + const int num_open_fd = 10; + if (nftw(path_str, _remove_files, num_open_fd, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0) fail("Could not remove directory: %s (%s)", path_str, strerror(errno)); - } else { - fail("Could not remove path: %s (not a file or directory)", path_str, strerror(errno)); + } else { fail("Could not remove path: %s (not a file or directory)", path_str, strerror(errno)); } } |
