]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
rm: be more careful when using a replacement errno value
authorJim Meyering <meyering@redhat.com>
Wed, 5 Sep 2012 14:48:50 +0000 (16:48 +0200)
committerJim Meyering <meyering@redhat.com>
Wed, 5 Sep 2012 15:31:00 +0000 (17:31 +0200)
* src/remove.c (excise): Tighten the test for when we defer to an
old errno value: instead of relying solely on an FTS_DNR (unreadable
directory) failure, also test current and replacement errno values.
This change would also have solved the problem addressed by commit
v8.19-106-g57dd067.  For more info, see http://bugs.gnu.org/12339#113

src/remove.c

index 847a5cc4a473aa9edfc41354c1c548cb8c23afad..a141718c9fa8ffc7caccf2a1dd2d53d793cf062d 100644 (file)
@@ -392,11 +392,13 @@ excise (FTS *fts, FTSENT *ent, struct rm_options const *x, bool is_dir)
   if (ignorable_missing (x, errno))
     return RM_OK;
 
-  /* When failing to rmdir an unreadable directory, the typical
-     errno value is EISDIR, but that is not as useful to the user
-     as the errno value from the failed open (probably EPERM).
-     Use the earlier, more descriptive errno value.  */
-  if (ent->fts_info == FTS_DNR)
+  /* When failing to rmdir an unreadable directory, we see errno values
+     like EISDIR or ENOTDIR, but they would be meaningless in a diagnostic.
+     When that happens and the errno value from the failed open is EPERM
+     or EACCES, use the earlier, more descriptive errno value.  */
+  if (ent->fts_info == FTS_DNR
+      && (errno == ENOTEMPTY || errno == EISDIR || errno == ENOTDIR)
+      && (ent->fts_errno == EPERM || ent->fts_errno == EACCES))
     errno = ent->fts_errno;
   error (0, errno, _("cannot remove %s"), quote (ent->fts_path));
   mark_ancestor_dirs (ent);