summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2012-09-05 16:48:50 +0200
committerJim Meyering <meyering@redhat.com>2012-09-05 17:31:00 +0200
commitccbd3f3b290cb1bbed6a91361389bb936446621c (patch)
tree5134796e2f99d1ecf5807a52d4d0673ad20853a6
parent57dd06703cb89ba53d05af95c11e89a2ca51af5c (diff)
downloadcoreutils-ccbd3f3b290cb1bbed6a91361389bb936446621c.tar.xz
rm: be more careful when using a replacement errno value
* 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
-rw-r--r--src/remove.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/remove.c b/src/remove.c
index 847a5cc4a..a141718c9 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -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);