summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2006-06-26 13:02:01 +0000
committerJim Meyering <jim@meyering.net>2006-06-26 13:02:01 +0000
commit78b166d1b163df894d567b79d3bb5744156fb0fe (patch)
tree7f91488762f0ce8af7959d3c89a09ba9904d1cbf /src
parent9cabe37ac9a127f76e1f414ed8c297e3bf32feaa (diff)
downloadcoreutils-78b166d1b163df894d567b79d3bb5744156fb0fe.tar.xz
* NEWS: rm no longer fails to remove an empty, unreadable directory
* src/remove.c (remove_cwd_entries): If we can't open a directory, and the failure is not being ignored, try to remove the directory with rmdir (aka unlinkat-with-AT_REMOVEDIR), in case it's empty. Problem report and test case from Paul Eggert in <http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/7425>. * tests/rm/empty-inacc: New test, for the above.
Diffstat (limited to 'src')
-rw-r--r--src/remove.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/remove.c b/src/remove.c
index bfb0a3264..076ad64c3 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -1125,13 +1125,28 @@ remove_cwd_entries (DIR **dirp,
x, errno, subdir_sb, ds, NULL);
if (subdir_dirp == NULL)
{
+ status = RM_ERROR;
+
/* CAUTION: this test and diagnostic are identical to
those following the other use of fd_to_subdirp. */
- if (errno != ENOENT || !x->ignore_missing_files)
- error (0, errno,
- _("cannot remove %s"), quote (full_filename (f)));
- AD_mark_as_unremovable (ds, f);
- status = RM_ERROR;
+ if (errno == ENOENT && x->ignore_missing_files)
+ {
+ /* With -f, don't report "file not found". */
+ }
+ else
+ {
+ /* Upon fd_to_subdirp failure, try to remove F directly,
+ in case it's just an empty directory. */
+ int saved_errno = errno;
+ if (unlinkat (dirfd (*dirp), f, AT_REMOVEDIR) == 0)
+ status = RM_OK;
+ else
+ error (0, saved_errno,
+ _("cannot remove %s"), quote (full_filename (f)));
+ }
+
+ if (status == RM_ERROR)
+ AD_mark_as_unremovable (ds, f);
break;
}
@@ -1214,6 +1229,9 @@ remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir,
{
/* If fd_to_subdirp fails due to permissions, then try to
remove DIR via rmdir, in case it's just an empty directory. */
+ /* This use of rmdir just works, at least in the sole test I
+ have that exercises this code, but it'll soon go, to be
+ replaced by a use of unlinkat-with-AT_REMOVEDIR. */
if (rmdir (dir) == 0)
return RM_OK;