-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Description
Since commit 51b557a, tools are catching their own SIGPIPE signals. This is wrong: the caller needs to be the one handling these. This is the long-standing behavior for *nix utilities. For example:
$ seq 10000 | head -n1
1No error generated, but seq is being killed by SIGPIPE:
$ strace seq 10000 | head -n1
...
write(1, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14"..., 8192) = 8192
1
write(1, "\n1861\n1862\n1863\n1864\n1865\n1866\n1"..., 4096) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=3503448, si_uid=1000} ---
+++ killed by SIGPIPE +++It is the caller (the shell, here) that is filtering out SIGPIPE. The tool itself should not catch the signal, and caller are expecting tools to be killed early by SIGPIPE so that needless CPU resources (and time) are not wasted. (For example, when using head, or grep -mN, etc.)
The SIGPIPE handler should be left explicitly untouched, i.e. set to SIG_DFL. If the error is wanted, callers (shells) can be configured to report it:
$ set -o pipefail
$ seq 10000 | head -n1
1
$ echo $?
141The LLVM tool behavior is incorrect:
$ llvm-objdump -d /bin/true | head -n1
error: write on a pipe with no readerAnd we can see that the signal is being caught internally:
$ strace llvm-objdump -d /bin/true | head -n1
...
write(1, "\n/bin/true:\tfile format elf64-x8"..., 95) = 95
write(1, " 1000: f3 0f 1e fa "..., 48
) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=3503786, si_uid=1000} ---
...
rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fa15add7520}, NULL, 8) = 0
...
lseek(2, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
newfstatat(2, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x19), ...}, AT_EMPTY_PATH) = 0
write(2, "error: write on a pipe with no r"..., 38error: write on a pipe with no reader
) = 38
exit_group(74) = ?
+++ exited with 74 +++And errno 74 is also wrong here (EBADMSG). Again, setting pipefail can expose this wrong error too:
$ set -o pipefail
$ llvm-objdump -d /bin/true | head -n1
...
$ echo $?
74But this errno is not correct. :(
Metadata
Metadata
Assignees
Type
Projects
Status