Skip to content

fix(cli): reset SIGPIPE to default so piping to head/tail exits quietly - #733

Open
platinummonkey wants to merge 1 commit into
mainfrom
fix/broken-pipe-panic
Open

fix(cli): reset SIGPIPE to default so piping to head/tail exits quietly#733
platinummonkey wants to merge 1 commit into
mainfrom
fix/broken-pipe-panic

Conversation

@platinummonkey

Copy link
Copy Markdown
Collaborator

Summary

  • Piping pup output into head/tail (e.g. pup logs search --query='*' | head -n 20) panicked with failed printing to stdout: Broken pipe (os error 32). Rust ignores SIGPIPE by default, so a closed pipe surfaces as an EPIPE error, which println!/print! turn into a panic instead of a clean exit.
  • Reset SIGPIPE to SIG_DFL at process start — the standard fix used by ripgrep, fd, and other Unix CLI tools — so the process now exits quietly via the signal instead of panicking.

Changes

  • src/main.rs: add reset_sigpipe(), called at the top of main() (native target), plus a unit test (reset_sigpipe_tests::sets_default_disposition)
  • Cargo.toml/Cargo.lock: add libc as a cfg(unix)-only target dependency (already a transitive dependency at the pinned version, no new crate introduced)

Testing

  • Built both the pre-fix and post-fix binaries and ran pup completions bash | head -n 1:
    • Before: panics with thread 'main' panicked ... failed to write completion file: Broken pipe, exit code 101
    • After: exits cleanly via SIGPIPE, exit code 141
  • cargo test reset_sigpipe passes
  • cargo fmt --check passes
  • cargo clippy --all-targets -- -D warnings passes

Related Issues

Fixes the broken pipe panic reported when piping pup output to head.


🤖 Generated with Claude Code

…uietly

Piping pup output into `head`/`tail` (e.g. `pup logs search --query='*' |
head -n 20`) panicked with "failed printing to stdout: Broken pipe (os
error 32)". Rust ignores SIGPIPE by default, so a closed pipe surfaces
as an EPIPE error, which println!/print! turn into a panic instead of
a clean exit.

Reset SIGPIPE to SIG_DFL at process start, the standard fix used by
ripgrep, fd, and other Unix CLI tools, so the process now exits
quietly via the signal instead of panicking.

- src/main.rs: add reset_sigpipe(), called at the top of main()
- Cargo.toml/Cargo.lock: add libc as a unix-only target dependency

Verified by building both the pre-fix and post-fix binaries and
running `pup completions bash | head -n 1`: the old binary panicked
(exit 101), the new binary exits cleanly via SIGPIPE (exit 141).
cargo fmt --check and cargo clippy --all-targets -- -D warnings both
pass, and the new reset_sigpipe_tests::sets_default_disposition unit
test passes.

Environment: Datadog workspace

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@platinummonkey
platinummonkey requested a review from a team as a code owner August 14, 2026 18:21
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.

1 participant