Skip to content

Commit b89bcef

Browse files
committed
Reapply: Add an error message to the default SIGPIPE handler
UNIX03 conformance requires utilities to flush stdout before exiting and raise an error if writing fails. Flushing already happens on a call to exit and thus automatically on a return from main. Write failure is then detected by LLVM's default SIGPIPE handler. The handler already exits with a non-zero code, but conformance additionally requires an error message. First reapply attempt I hadn't noticed the test had changed, hopefully this goes better.
1 parent 51d8473 commit b89bcef

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

llvm/lib/Support/Unix/Signals.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,10 @@ void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
432432
}
433433

434434
void llvm::sys::DefaultOneShotPipeSignalHandler() {
435+
// UNIX03 conformance requires a non-zero exit code and an error message
436+
// to stderr when writing to a closed stdout fails.
437+
errs() << "error: write on a pipe with no reader\n";
438+
435439
// Send a special return code that drivers can check for, from sysexits.h.
436440
exit(EX_IOERR);
437441
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## Test that when writing to a closed stdout, LLVM tools finish with a non-zero
2+
## exit code and an error message on stderr. The test uses llvm-cxxfilt, but
3+
## it's a logic from the default SIGPIPE handler, so it applies to all the tools.
4+
## This is required for UNIX03 conformance.
5+
6+
# UNSUPPORTED: system-windows
7+
8+
# RUN: not %python %s llvm-cxxfilt 2>&1 | FileCheck %s
9+
# CHECK: error: write on a pipe with no reader
10+
11+
import subprocess
12+
import sys
13+
14+
with subprocess.Popen([sys.argv[1]], stdout=subprocess.PIPE, stdin=subprocess.PIPE) as process:
15+
process.stdout.close()
16+
17+
# llvm-cxxfilt with no extra arguments runs interactively and writes input
18+
# to output. Writing continuously to stdin should trigger SIGPIPE when the
19+
# subprocess attempts to write out bytes to a closed stdout.
20+
try:
21+
while True:
22+
process.stdin.write("foo\n".encode("utf-8"))
23+
except BrokenPipeError:
24+
# Clear stdin, pipe is broken and closing it on cleanup will raise an exception.
25+
process.stdin = None
26+
sys.exit(process.returncode)

0 commit comments

Comments
 (0)