Repository navigation
Conversation
A compiled program whose output is piped into head, less or grep -q dies on EPIPE with 'bend: a short write on a standard stream' and exit 1. Unix tools stop quietly there instead, ended by SIGPIPE. io_out and io_sync now share io_short: on EPIPE against stdout or stderr the runtime restores the default SIGPIPE disposition and raises it, so the program ends the way yes | head -1 does (status 141, nothing on stderr). Every other failed write, and every write to a file or a socket, still answers err_fail as before. The JS lane exits 141 on the same condition.
|
Thanks for picking this up. #1470 fixes the same issue, and this PR has two gaps that it closes:
Smaller points: #1470 covers the C lane, the JS lane and the in-process |
|
Agreed on every point — closing this in favour of #1470.
Thanks for taking the time to write this up — the Closing as superseded. Not adding a test-only PR on top of #1470; if the |
|
Closing as superseded by #1470, per the review above. |
Fixes #1467.
A compiled program whose output is piped into
head,lessorgrep -qdies on
EPIPEwithand exits 1. Unix tools stop quietly in that spot instead, ended by
SIGPIPE:yes | head -1writes nothing to stderr and reports 141.bend2/comp.tsignoredSIGPIPEinio_loop(so a dead pipe cannot killthe runtime mid-turn), which turned every broken pipe into that message.
io_outandio_syncnow share oneio_shorthelper: onEPIPEagainst
stdoutorstderrthe runtime restores the defaultSIGPIPEdisposition and raises it, so the program ends the way
yesdoes —status 141, nothing on stderr. Every other failed write, and every write
to a file or a socket, still answers
err_failexactly as before, sinceonly
stdoutandstderrreachio_out.The JS lane gets the same treatment:
EPIPEon fd 1 or 2 exits 141instead of printing the message and exiting 1.
The reproducer from the report, built at
2.0.36and after this change:Same under
bun:bend flood.bend -o flood.js && bun flood.js | head -1goes from
bend: a short write on a standard stream/ exit 1 to a silent141.
Not covered by a
tests/iocase: the gate runs every test with its stdouton a pipe it never closes, so a
#|expectation cannot express a brokenpipe. Verified by hand in both lanes instead, plus the whole
tests/ioand
tests/haltsuites interpreted against the unmodified baseline, whichmoves nothing.