Send signal as a string in ClientProcess.kill (fixes "missing signal in xpc message")#1997
Open
chengboonrong wants to merge 1 commit into
Open
Conversation
chengboonrong
force-pushed
the
claude/open-source-contribution-055112
branch
2 times, most recently
from
July 23, 2026 13:25
ef05b81 to
d216f25
Compare
The API server reads the `.signal` XPC key as a string (via `xpc_dictionary_get_string`) and resolves it against the Linux signal table, but `ClientProcess.kill(_:)` wrote it with `set(key: .signal, value: Int64(signal))`. `xpc_dictionary_get_string` returns nil for an integer value, so every signal sent through this path was rejected with `invalidArgument: "missing signal in xpc message"`. This path is used both by the public `ContainerAPIClient` (`ClientProcess.kill`) and by the foreground CLI's signal forwarding, so `^C` on a `-t` container and `SIGWINCH` terminal-resize forwarding were both broken. Send the canonical signal name instead, matching the already-working `ContainerClient.kill` path. Because the server resolves names against the Linux table, sending the name (rather than the raw macOS number) also keeps signals whose numbers differ between macOS and Linux correct (e.g. host SIGUSR1=30 -> "USR1" -> Linux 10, instead of Linux SIGPWR=30). Falls back to the numeric string for real-time signals that have no platform name. Fixes apple#1941 Fixes apple#1876 Fixes apple#1747 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Chris Cheng <chengchris8715@gmail.com>
chengboonrong
force-pushed
the
claude/open-source-contribution-055112
branch
from
July 23, 2026 13:38
d216f25 to
47f23e4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ClientProcess.kill(_:)never delivered a signal: every call failed withinvalidArgument: "missing signal in xpc message".Signals cross the client→server boundary as an XPC dictionary value. There are
two client senders and one server reader:
ContainerClient.kill(thecontainer killCLI) sends the signal as astring name → the server reads a string → works.
ClientProcess.kill— used by the publicContainerAPIClientand by theforeground CLI's signal forwarding — sent an
Int64. The server reads.signalwithxpc_dictionary_get_string, which returnsnilfor an integervalue, so the request was always rejected.
Because
ClientProcess.killalso backs the foreground CLI's^C/SIGWINCHforwarding, this broke interactive
-tcontainers (^Ccouldn't stop them) andspammed stderr with the same error on terminal resize.
Fix
Send the canonical signal name, matching the already-working
ContainerClient.killpath:The server resolves signal strings against the Linux signal table, so
sending the name (rather than the raw macOS number) also keeps signals whose
numbers differ between macOS and Linux correct — e.g. host
SIGUSR1=30 →"USR1"→ Linux 10, instead of being misdelivered as LinuxSIGPWR=30. Fallsback to the numeric string for real-time signals that have no platform name.
Tests
Adds
SignalWireFormatTests, which replicates the exact value the client putson the wire and the exact resolution the server performs, covering common
signals, the platform-divergent case (
SIGUSR1), and the non-empty-stringcontract.
Verified locally:
swift build,swift format lint --strict, and the newtests all pass.
Fixes #1941
Fixes #1876
Fixes #1747
🤖 Generated with Claude Code