[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug #27923] rm -f gives an error when trying to delete a non-existe

From: Jim Meyering
Subject: Re: [bug #27923] rm -f gives an error when trying to delete a non-existent file on a read-only filesystem
Date: Tue, 03 Nov 2009 12:04:52 +0100

Steven Drake wrote:
>  Summary: rm -f gives an error when trying to delete a non-existent
>           file on a read-only filesystem
> Eg:
> /bin/rm: cannot remove `non-existent-file': Read-only file system.
> On a linux/glibc system the unlinkat syscall will set errno to EROFS and
> nonexistent_file_errno() does not perform any checks
> for this case.  (Another rm does an fts_open/fts_read and ignores
> the file if fts_info is FST_NS before trying to unlink it.)

Thanks for reporting that.
It also affected the very latest versions.

I expect to fix it with this patch once I've added a test.

>From 77b6a86cf1cc87635793202ec869528f07f5fba3 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 3 Nov 2009 12:01:40 +0100
Subject: [PATCH] rm -f: ignore EROFS when it's really ENOENT

rm -f must not print a diagnostic for a nonexistent file.  However,
most linux-based kernel unlinkat functions set errno to EROFS when
the named file (regardless of whether it exists) would lie on a
read-only file system.  remove.c now performs an extra fstatat call
in that case, to determine whether the file exists.
* src/remove.c (excise): Map EROFS to ENOENT, if a file is nonexistent.
Reported by Steven Drake in <http://savannah.gnu.org/bugs/?27923>.
* NEWS (Changes in behavior): Mention it.
 NEWS         |    6 ++++++
 src/remove.c |   12 ++++++++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index 0760775..03ed83f 100644
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,12 @@ GNU coreutils NEWS                                    -*- 
outline -*-

   echo and printf now interpret \e as the Escape character (0x1B).

+  rm -f /read-only-fs/nonexistent now succeeds and prints no diagnostic
+  on systems with an unlinkat syscall that sets errno to EROFS in that case.
+  Before, it would fail with a "Read-only file system" diagnostic.
+  Also, "rm /read-only-fs/nonexistent" now reports "file not found" rather
+  than the less precise "Read-only file system" error.
 ** New features

   env and printenv now accept the option --null (-0), as a means to
diff --git a/src/remove.c b/src/remove.c
index 87fb32b..a234829 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -437,6 +437,18 @@ excise (FTS *fts, FTSENT *ent, struct rm_options const *x, 
bool is_dir)
       return RM_OK;

+  /* The unlinkat from kernels like linux-2.6.32 reports EROFS even for
+     nonexistent files.  When the file is indeed missing, map that to ENOENT,
+     so that rm -f ignores it, as required.  Even without -f, this is useful
+     because it makes rm print the more precise diagnostic.  */
+  if (errno == EROFS)
+    {
+      struct stat st;
+      if ( ! (fstatat (fts->fts_cwd_fd, ent->fts_accpath, &st,
+                       AT_SYMLINK_NOFOLLOW) && errno == ENOENT))
+        errno = EROFS;
+    }
   if (ignorable_missing (x, errno))
     return RM_OK;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]