[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;
--
1.6.5.2.292.g1cda2