summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-09-21 14:05:49 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2022-09-24 16:34:31 -0700
commiteb7841426ce8cfb0150d4d2f4879ce455005fbbb (patch)
treef0a40ea685f49dd2d7de8716b84e99d0f9a72ee4 /tests
parent5a14ccad485f62d759157e925c7fddf33b9a5829 (diff)
downloadcoreutils-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')
-rwxr-xr-xtests/rm/rm-readdir-fail.sh1
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_