From: Collin Funk Date: Wed, 20 May 2026 01:10:51 +0000 (-0700) Subject: shred: preserve the ENXIO errno from open X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=4d63accc0896a9b0d0d817795afae616f081bbc1;p=thirdparty%2Fcoreutils.git shred: preserve the ENXIO errno from open This fixes an issue in unreleased commit f77f365ef (shred: don't block when opening FIFOs with no readers, 2026-05-09). * src/shred.c: Save the errno before calling stat and use it in the error message. * tests/shred/fifo.sh: Call getlimits_ and uses_strace_. Add a test case. --- diff --git a/src/shred.c b/src/shred.c index b5a212c973..d96fefc781 100644 --- a/src/shred.c +++ b/src/shred.c @@ -1151,13 +1151,15 @@ wipefile (char *name, char const *qname, if (fd < 0) { struct stat st; + const int open_errno = errno; /* Try to give a more meaningful error message if we attempt to open a FIFO with no readers. */ - if (errno == ENXIO && 0 <= stat (name, &st) && S_ISFIFO (st.st_mode)) + if (open_errno == ENXIO && 0 <= stat (name, &st) + && S_ISFIFO (st.st_mode)) error (0, 0, _("%s: invalid file type"), qname); else - error (0, errno, _("%s: failed to open for writing"), qname); + error (0, open_errno, _("%s: failed to open for writing"), qname); return false; } diff --git a/tests/shred/fifo.sh b/tests/shred/fifo.sh index f182d3c9e2..40af9c2f58 100755 --- a/tests/shred/fifo.sh +++ b/tests/shred/fifo.sh @@ -18,6 +18,26 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ shred +getlimits_ +uses_strace_ + +open_stat_fail () +{ + strace --quiet=all -o /dev/null -P file -e inject=open,openat:error=ENXIO \ + -e inject=stat,newfstatat:error=ENOSYS "$@" +} + +# If open fails with ENXIO and the subsequent stat fails, e.g., because the +# FIFO was removed or it is a character or block special associated with a +# non-existent device, we should use the error number from open. +if open_stat_fail true; then + cat <exp-err || framework_failure_ +shred: file: failed to open for writing: $ENXIO +EOF + returns_ 1 open_stat_fail shred file >out 2>err || fail=1 + compare exp-err err || fail=1 + compare /dev/null out || fail=1 +fi mkfifo_or_skip_ fifo