aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Groffen <grobian@gentoo.org>2017-12-28 17:00:28 +0100
committerFabian Groffen <grobian@gentoo.org>2017-12-28 17:00:28 +0100
commit8e9d0f3e53f2b102e47a98f419b196a2184694c2 (patch)
tree9399c7c3cf7d009c2766426992b2b63c90d53c96 /libq/xmkdir.c
parentFix -Wmaybe-uninitialized. (diff)
downloadportage-utils-8e9d0f3e53f2b102e47a98f419b196a2184694c2.tar.gz
portage-utils-8e9d0f3e53f2b102e47a98f419b196a2184694c2.tar.bz2
portage-utils-8e9d0f3e53f2b102e47a98f419b196a2184694c2.zip
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.
Diffstat (limited to 'libq/xmkdir.c')
-rw-r--r--libq/xmkdir.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/libq/xmkdir.c b/libq/xmkdir.c
index 265cb5bc..9a120ae2 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);
}