commit: 8e9d0f3e53f2b102e47a98f419b196a2184694c2
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 28 16:00:28 2017 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Thu Dec 28 16:00:28 2017 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=8e9d0f3e
rm_rf_at: fix recurse logic for non-Linux
EISDIR is non-POSIX used by the Linux kernel, but not returned on e.g.
Darwin, so use the EISDIR shortcut, if we can, else perform a stat to
figure out if we're dealing with a directory or not.
libq/xmkdir.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libq/xmkdir.c b/libq/xmkdir.c
index 265cb5b..9a120ae 100644
--- a/libq/xmkdir.c
+++ b/libq/xmkdir.c
@@ -65,8 +65,14 @@ rm_rf_at(int dfd, const char *path)
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
if (unlinkat(subdfd, de->d_name, 0) == -1) {
- if (unlikely(errno != EISDIR))
- errp("could not unlink %s", de->d_name);
+ if (unlikely(errno != EISDIR)) {
+ struct stat st;
+ /* above is a linux short-cut, we really just
want to
+ * know whether we're really with a directory
or not */
+ if (fstatat(subdfd, de->d_name, &st, 0) != 0 ||
+ !(st.st_mode & S_IFDIR))
+ errp("could not unlink %s", de->d_name);
+ }
rm_rf_at(subdfd, de->d_name);
unlinkat(subdfd, de->d_name, AT_REMOVEDIR);
}