summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2009-11-03 12:01:40 +0100
committerJim Meyering <meyering@redhat.com>2009-11-03 14:14:00 +0100
commit7bf2e3db23bd0a9ed59d95a683edd188fa52a033 (patch)
tree3f77ae8bbb8370e44d0cf7209ccb45af975db8b0
parent87bf834dd36646f0e413c1afeb5d498079d1bb14 (diff)
downloadcoreutils-7bf2e3db23bd0a9ed59d95a683edd188fa52a033.tar.xz
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.
-rw-r--r--NEWS6
-rw-r--r--THANKS1
-rw-r--r--src/remove.c12
3 files changed, 19 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 076077525..03ed83ff3 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/THANKS b/THANKS
index 5efe2fa1e..c583e2af5 100644
--- a/THANKS
+++ b/THANKS
@@ -541,6 +541,7 @@ Stephen Smoogen smooge@mindspring.com
Steve McConnel steve@acadcomp.sil.org
Steve McIntyre steve@einval.com
Steve Ward planet36@gmail.com
+Steven Drake sbd@users.sourceforge.net
Steven G. Johnson stevenj@alum.mit.edu
Steven Mocking ufo@quicknet.nl
Steven Parkes smparkes@smparkes.net
diff --git a/src/remove.c b/src/remove.c
index 87fb32bf9..c4b93fe7e 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 ( ! (lstatat (fts->fts_cwd_fd, ent->fts_accpath, &st)
+ && errno == ENOENT))
+ errno = EROFS;
+ }
+
if (ignorable_missing (x, errno))
return RM_OK;