diff options
author | Jim Meyering <meyering@redhat.com> | 2009-11-03 12:01:40 +0100 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2009-11-03 14:14:00 +0100 |
commit | 7bf2e3db23bd0a9ed59d95a683edd188fa52a033 (patch) | |
tree | 3f77ae8bbb8370e44d0cf7209ccb45af975db8b0 | |
parent | 87bf834dd36646f0e413c1afeb5d498079d1bb14 (diff) | |
download | coreutils-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-- | NEWS | 6 | ||||
-rw-r--r-- | THANKS | 1 | ||||
-rw-r--r-- | src/remove.c | 12 |
3 files changed, 19 insertions, 0 deletions
@@ -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 @@ -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; |