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);
                }

Reply via email to