fix(cat): suppress broken-pipe error when piped into head#184
Conversation
When cat pipes into head, head exits after reading enough lines and closes the pipe. cat's next write gets EPIPE, which was being printed to stderr. In bash, SIGPIPE silently terminates the writer. Add IsBrokenPipe helper and use it in cat to silently exit on EPIPE. Closes #163 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@codex can you explain how the go runtime handles SIGPIPE? I recall there being special cases for stderr/out/in file descriptors or something like this? |
|
Yes — you’re remembering correctly. In Go on Unix,
So your memory of “special cases for stdio descriptors” is exactly right; the special-case is specifically for stdout/stderr, not stdin. In this PR’s context, that maps to the fix: rshell now treats broken pipe ( Commands I used
If you want, I can also give a tiny repro program showing each case ( |
1 similar comment
|
Yes — you’re remembering correctly. In Go on Unix,
So your memory of “special cases for stdio descriptors” is exactly right; the special-case is specifically for stdout/stderr, not stdin. In this PR’s context, that maps to the fix: rshell now treats broken pipe ( Commands I used
If you want, I can also give a tiny repro program showing each case ( |
Summary
cat file | head -n 3was printingcat: file: write |1: broken pipeto stderrbuiltins.IsBrokenPipe()helper to detect EPIPE errors (the Go equivalent of SIGPIPE in bash)catto silently exit on broken pipe instead of printing an error, matching bash behaviorcat | headpipingBefore
After
Test plan
go run cmd/rshell/main.go --allow-all-commands --allowed-paths /tmp -c 'cat bigfile | head -n 3'— no stderr outputcat -n(line-processing path) also suppresses broken pipe silentlygo test ./builtins/cat/)go test ./...)cat_head_no_broken_pipe.yamlpasses🤖 Generated with Claude Code