diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2022-09-21 14:05:49 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2022-09-24 16:34:31 -0700 |
commit | eb7841426ce8cfb0150d4d2f4879ce455005fbbb (patch) | |
tree | f0a40ea685f49dd2d7de8716b84e99d0f9a72ee4 /tests/rm | |
parent | 5a14ccad485f62d759157e925c7fddf33b9a5829 (diff) | |
download | coreutils-eb7841426ce8cfb0150d4d2f4879ce455005fbbb.tar.gz |
rm: fix diagnostics on I/O error
I ran into this problem when attempting to recursively
remove a directory in a filesystem on flaky hardware.
Although the underlying readdir syscall failed with errno == EIO,
rm issued no diagnostic about the I/O error.
Without this patch I see this behavior:
$ rm -fr baddir
rm: cannot remove 'baddir': Directory not empty
$ rm -ir baddir
rm: descend into directory 'baddir'? y
rm: remove directory 'baddir'? y
rm: cannot remove 'baddir': Directory not empty
With this patch I see the following behavior, which
lets the user know about the I/O error when rm tries
to read baddir's directory entries:
$ rm -fr baddir
rm: cannot remove 'baddir': Input/output error
$ rm -ir baddir
rm: cannot remove 'baddir': Input/output error
* src/remove.c (Ternary): Remove. All uses removed.
(get_dir_status): New static function.
(prompt): Last arg is now directory status, not ternary.
Return RM_USER_ACCEPTED if user explicitly accepted.
All uses changed.
Report any significant error in directory status right away.
(prompt, rm_fts): Use get_dir_status to get directory status lazily.
(excise): Treat any FTS_DNR errno as being more descriptive, not
just EPERM and EACCESS. For example, EIO is more descriptive.
(rm_fts): Distinguish more clearly between explicit and implied
user OK.
* src/remove.h (RM_USER_ACCEPTED): New constant.
(VALID_STATUS): Treat it as valid.
* src/system.h (is_empty_dir): Remove, replacing with ...
(directory_status): ... this more-general function.
All uses changed. Avoid undefined behavior of looking at
a non-null readdir pointer after corresponding closedir.
* tests/rm/rm-readdir-fail.sh: Adjust test of internals
to match current behavior.
Diffstat (limited to 'tests/rm')
-rwxr-xr-x | tests/rm/rm-readdir-fail.sh | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/tests/rm/rm-readdir-fail.sh b/tests/rm/rm-readdir-fail.sh index a77d5225f..9dbf9380c 100755 --- a/tests/rm/rm-readdir-fail.sh +++ b/tests/rm/rm-readdir-fail.sh @@ -112,6 +112,7 @@ done # (with ENOENT in this case but it could be anything). cat <<EOF > exp rm: cannot remove 'dir' +Failed to get dirent rm: traversal failed: dir EOF sed 's/\(rm:.*\):.*/\1/' errt > err || framework_failure_ |