summaryrefslogtreecommitdiff
path: root/src/rmdir.c
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2008-01-30 13:43:15 +0100
committerJim Meyering <meyering@redhat.com>2008-01-30 13:51:38 +0100
commited5c4e770a27862813c0182be8680abeb005d15b (patch)
tree9eff6d3bb6c974405a392116607daddde202b0ef /src/rmdir.c
parent194ca7b3f9d7992c6c40804d8d15fda5e257604a (diff)
downloadcoreutils-ed5c4e770a27862813c0182be8680abeb005d15b.tar.xz
Improve "rmdir --ignore-fail-on-non-empty"
* src/rmdir.c (remove_parents, main): With --ignore-fail-on-non-empty, suppress a diagnostic also for other errno values, which can arise with read-only media or when the parent directory has the immutable attribute (set via chattr +i). (errno_may_be_empty, ignorable_failure): New functions. * src/remove.c (is_empty_dir): Move function to ... * src/system.h (is_empty_dir): ...here, and make it inline. Suggested by Josselin Mouette in <http://bugs.debian.org/363011> via Bob Proulx. * NEWS: Mention the improvement.
Diffstat (limited to 'src/rmdir.c')
-rw-r--r--src/rmdir.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/rmdir.c b/src/rmdir.c
index 96aa9af22..bb1a0c8b3 100644
--- a/src/rmdir.c
+++ b/src/rmdir.c
@@ -74,13 +74,41 @@ static struct option const longopts[] =
/* Return true if ERROR_NUMBER is one of the values associated
with a failed rmdir due to non-empty target directory. */
-
static bool
errno_rmdir_non_empty (int error_number)
{
return (error_number == RMDIR_ERRNO_NOT_EMPTY);
}
+/* Return true if when rmdir fails with errno == ERROR_NUMBER
+ the directory may be empty. */
+static bool
+errno_may_be_empty (int error_number)
+{
+ switch (error_number)
+ {
+ case EACCES:
+ case EPERM:
+ case EROFS:
+ case EEXIST:
+ case EBUSY:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* Return true if an rmdir failure with errno == error_number
+ for DIR is ignorable. */
+static bool
+ignorable_failure (int error_number, char const *dir)
+{
+ return (ignore_fail_on_non_empty
+ && (errno_rmdir_non_empty (error_number)
+ || (errno_may_be_empty (error_number)
+ && is_empty_dir (AT_FDCWD, dir))));
+}
+
/* Remove any empty parent directories of DIR.
If DIR contains slash characters, at least one of them
(beginning with the rightmost) is replaced with a NUL byte.
@@ -113,8 +141,7 @@ remove_parents (char *dir)
if (!ok)
{
/* Stop quietly if --ignore-fail-on-non-empty. */
- if (ignore_fail_on_non_empty
- && errno_rmdir_non_empty (errno))
+ if (ignorable_failure (errno, dir))
{
ok = true;
}
@@ -210,8 +237,7 @@ main (int argc, char **argv)
if (rmdir (dir) != 0)
{
- if (ignore_fail_on_non_empty
- && errno_rmdir_non_empty (errno))
+ if (ignorable_failure (errno, dir))
continue;
/* Here, the diagnostic is less precise, since we have no idea