Skip to content

Honor MSG_NOSIGNAL on AF_INET loopback stream send#858

Open
brandonpayton wants to merge 1 commit into
mainfrom
fix/msg-nosignal-inet-loopback
Open

Honor MSG_NOSIGNAL on AF_INET loopback stream send#858
brandonpayton wants to merge 1 commit into
mainfrom
fix/msg-nosignal-inet-loopback

Conversation

@brandonpayton

Copy link
Copy Markdown
Member

Contract: MSG_NOSIGNAL must suppress SIGPIPE on broken streams

send(fd, buf, MSG_NOSIGNAL) on a broken connection must return EPIPE without raising SIGPIPE. sys_send honored this only on the AF_UNIX branch; the AF_INET loopback path called sys_write directly, which unconditionally raises SIGPIPE on a closed pipe. A loopback TCP server whose peer closed its read side got a spurious SIGPIPE — terminating a process using the default disposition, the exact outcome MSG_NOSIGNAL exists to prevent.

This also contradicted a documented guarantee (docs/posix-status.md: "MSG_NOSIGNAL is honored for stream/broken-pipe paths"); the fix makes that statement true.

Fix

Apply the same save/clear-SIGPIPE handling the AF_UNIX branch already uses to the AF_INET loopback path. EPIPE is still returned; only the signal is suppressed.

ABI

No change.

Validation

  • cargo test -p kandelo --target aarch64-apple-darwin --lib964 pass, including new test_send_msg_nosignal_inet_loopback (loopback INET connect/accept → close server end → send(MSG_NOSIGNAL) → assert EPIPE + no pending SIGPIPE). Verified the test fails without the fix (SIGPIPE raised).
  • scripts/check-abi-version.sh — snapshot in sync.

🤖 Generated with Claude Code

`send(fd, buf, MSG_NOSIGNAL)` on a broken connection must return EPIPE without
raising SIGPIPE. `sys_send` honored this only on the AF_UNIX branch; the AF_INET
loopback path called `sys_write` directly, which unconditionally raises SIGPIPE
on a closed pipe. So a loopback TCP server whose peer closed its read side got a
spurious SIGPIPE — terminating a process using the default disposition — the
exact outcome MSG_NOSIGNAL exists to prevent. This also contradicted the
documented guarantee (docs/posix-status.md: "MSG_NOSIGNAL is honored for
stream/broken-pipe paths").

Apply the same save/clear-SIGPIPE handling the AF_UNIX branch already uses to the
AF_INET loopback path. EPIPE is still returned; only the signal is suppressed.

No ABI change.

Validation: `cargo test -p kandelo --lib` (964 pass, incl. new
`test_send_msg_nosignal_inet_loopback` — a loopback INET connect/accept, close
the server end, `send(MSG_NOSIGNAL)`, assert EPIPE and no pending SIGPIPE;
verified to fail without the fix). `scripts/check-abi-version.sh` in sync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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