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.
---
 src/shred.c         |  6 ++++--
 tests/shred/fifo.sh | 20 ++++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/shred.c b/src/shred.c
index b5a212c97..d96fefc78 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 f182d3c9e..40af9c2f5 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 <<EOF >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
 
-- 
2.54.0


Reply via email to