diff options
author | Jim Meyering <jim@meyering.net> | 2006-10-03 13:13:09 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-10-03 13:13:09 +0000 |
commit | da9541f18e6985593b73c30d121605e8cff62a7b (patch) | |
tree | fa536023ddb705bdc539244b7dd8bf1c74c0f95b /src | |
parent | d2e7358a9be5b7f1b816e46f3a2cf151463f2208 (diff) | |
download | coreutils-da9541f18e6985593b73c30d121605e8cff62a7b.tar.xz |
With --force (-f), rm no longer fails for ENOTDIR.
* src/remove.c (ignorable_missing): New function.
Use it everywhere, rather than open-coding the test.
Andreas Schwab reported the ENOTDIR problem.
(ignorable_missing): Similarly, don't fail for ENAMETOOLONG.
* NEWS: Mention the bug fix.
* tests/rm/ignorable: New file. Test for the ENOTDIR case.
* tests/rm/ignore-name-too-long: New file. Test for ENAMETOOLONG.
* tests/rm/Makefile.am (TESTS): Add the new file names.
Diffstat (limited to 'src')
-rw-r--r-- | src/remove.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/remove.c b/src/remove.c index 1fcf79ff3..ed2c846e9 100644 --- a/src/remove.c +++ b/src/remove.c @@ -899,7 +899,7 @@ is_dir_lstat (char const *filename, struct stat *st) return RM_OK; \ } \ \ - if (errno == ENOENT && (X)->ignore_missing_files) \ + if (ignorable_missing (X, errno)) \ return RM_OK; \ } \ while (0) @@ -915,7 +915,7 @@ is_dir_lstat (char const *filename, struct stat *st) return RM_OK; \ } \ \ - if (errno == ENOENT && (X)->ignore_missing_files) \ + if (ignorable_missing (X, errno)) \ return RM_OK; \ \ if (errno == ENOTEMPTY || errno == EEXIST) \ @@ -923,6 +923,32 @@ is_dir_lstat (char const *filename, struct stat *st) } \ while (0) +/* When a function like unlink, rmdir, or fstatat fails with an errno + value of ERRNUM, return true if the specified file system object + is guaranteed not to exist; otherwise, return false. */ +static inline bool +nonexistent_file_errno (int errnum) +{ + /* Do not include ELOOP here, since the specified file may indeed + exist, but be (in)accessible only via too long a symlink chain. */ + switch (errnum) + { + case ENAMETOOLONG: + case ENOENT: + case ENOTDIR: + return true; + default: + return false; + } +} + +/* Encapsulate the test for whether the errno value, ERRNUM, is ignorable. */ +static inline bool +ignorable_missing (struct rm_options const *x, int errnum) +{ + return x->ignore_missing_files && nonexistent_file_errno (errnum); +} + /* Remove the file or directory specified by FILENAME. Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not. But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */ @@ -1014,7 +1040,7 @@ remove_entry (int fd_cwd, Dirstack_state const *ds, char const *filename, { if (fstatat (fd_cwd, filename, st, AT_SYMLINK_NOFOLLOW)) { - if (errno == ENOENT && x->ignore_missing_files) + if (ignorable_missing (x, errno)) return RM_OK; error (0, errno, _("cannot remove %s"), @@ -1195,7 +1221,7 @@ remove_cwd_entries (DIR **dirp, /* CAUTION: this test and diagnostic are identical to those following the other use of fd_to_subdirp. */ - if (errno == ENOENT && x->ignore_missing_files) + if (ignorable_missing (x, errno)) { /* With -f, don't report "file not found". */ } @@ -1281,7 +1307,7 @@ remove_dir (int fd_cwd, Dirstack_state *ds, char const *dir, { /* CAUTION: this test and diagnostic are identical to those following the other use of fd_to_subdirp. */ - if (errno == ENOENT && x->ignore_missing_files) + if (ignorable_missing (x, errno)) { /* With -f, don't report "file not found". */ } @@ -1426,7 +1452,7 @@ rm_1 (Dirstack_state *ds, char const *filename, { if (cache_fstatat (AT_FDCWD, filename, &st, AT_SYMLINK_NOFOLLOW) != 0) { - if (errno == ENOENT && x->ignore_missing_files) + if (ignorable_missing (x, errno)) return RM_OK; error (0, errno, _("cannot remove %s"), quote (filename)); return RM_ERROR; |