On 20/05/2026 02:19, Collin Funk wrote:
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

Good catch.

Re the test, there are various file _name_ "stat" functions,
so to increase coverage one might use similar techniques like
done in tests/ls/stat-free-symlinks.sh?
At least it would be good to verify the negative case also,
so something like:

if open_stat_fail true && ! open_stat_fail stat file; then
  ...
fi

cheers,
Padraig

Reply via email to