Skip to content

Conversation

tgrez
Copy link
Contributor

@tgrez tgrez commented Jul 12, 2025

Fixes #6876.

I was able to reproduce the original issue with both:

$ echo a | gzip -c > f.gz
$ perl -e '
      use POSIX qw(dup2);
      $SIG{PIPE} = "DEFAULT";
      pipe my ($read_end, $write_end);
      dup2 fileno $write_end, 1;
      close $read_end;
      exec "cat", "f.gz", "f.gz";
  '

cat: f.gz: EPIPE: Broken pipe
cat: f.gz: EPIPE: Broken pipe

and:

$ cat f.gz | false
cat: f.gz: EPIPE: Broken pipe

This PR fixes both cases.

Preparing yet another similar fix (previous ones: #8327 and #8312) I wonder if it makes sense to fix it for all binaries in a single place (at least for non-windows platforms), like in uucore::main macro in src/uucore_procs/src/lib.rs:

             // disable rust signal handlers (otherwise processes don't dump core after e.g. one SIGSEGV)
             #[cfg(unix)]
             uucore::disable_rust_signal_handlers().expect("Disabling rust signal handlers failed");
+            // When we receive a SIGPIPE signal, we want to terminate the process so
+            // that we don't print any error messages to stderr. Rust ignores SIGPIPE
+            // (see https://github.com/rust-lang/rust/issues/62569), so we restore it's
+            // default action here.
+            #[cfg(not(target_os = "windows"))]
+            unsafe {
+                libc::signal(libc::SIGPIPE, libc::SIG_DFL);
+            }
             let result = uumain(args);
             match result {
                 Ok(()) => uucore::error::get_exit_code(),

I can update this PR if such general fix makes sense.

@tgrez
Copy link
Contributor Author

tgrez commented Jul 12, 2025

Also, assuming those fish shell tests are located here: https://github.com/fish-shell/fish-shell/blob/e9bb150a41b64bc0d4cd3784d6fd54e0eabb4b42/tests/checks/pipestatus.fish#L200

This bug:

$ cat /dev/zero | dd > /not/a/valid/path
bash: /not/a/valid/path: No such file or directory
cat: /dev/zero: EPIPE: Broken pipe

is also fixed (verified in bash shell, but the error message is no longer present):

$ cat /dev/zero | dd > /not/a/valid/path
bash: /not/a/valid/path: No such file or directory
$

@tgrez tgrez marked this pull request as draft July 12, 2025 14:15
@tgrez
Copy link
Contributor Author

tgrez commented Jul 12, 2025

Setting to draft until CI errors are resolved.

Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/misc/stdbuf (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/misc/tee (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/timeout/timeout (passes in this run but fails in the 'main' branch)

Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)
Congrats! The gnu test tests/du/inodes is no longer failing!

@tgrez tgrez marked this pull request as ready for review July 14, 2025 17:11
@RenjiSann RenjiSann merged commit 50704da into uutils:main Jul 15, 2025
76 checks passed
@RenjiSann
Copy link
Collaborator

Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cat: /dev/zero: EPIPE: Broken pipe when running fish shell tests
2 participants