Repository navigation
feat: execute a command instead of an interactive shell - #44
Merged
Merged
Conversation
`dive <container> -- <command>...` runs the command in the dive environment instead of starting zsh, and exits with its exit status. - the command is passed through the sudo re-exec - exec failures exit with 127 (not found) or 126, as shells do - a child killed by a signal exits with 128 + signal - parent processes ignore SIGINT/SIGQUIT while waiting, like system(3), so Ctrl-C reaches the command without killing dive first CI runs a smoke test of the release binary against a container. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
assert_single_threaded() read /proc/self/task by path, which no longer resolves the calling process once inside the container's mount namespace. Every session logged "could not read /proc/self/task" and the check was skipped. Keep a handle on the original /proc from the first check, and look up self/task through it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ignoring SIGINT/SIGQUIT in the waiting parents only covered Ctrl-C on the terminal. Signals sent by other processes (kill, timeout, sudo relaying them) never reached the command: dive either waited for it to end, or exited and left it running. The parents now forward SIGHUP, SIGINT, SIGQUIT and SIGTERM to their child, except those generated by the kernel (Ctrl-C, terminal hangup), which already reach the command through its process group. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
raphaelcoeffic
force-pushed
the
feat/exec-command
branch
from
October 26, 2026 08:57
3bf62c7 to
103188d
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.
Stacked on #43: retarget to
mainonce it is merged.Changes
dive <container> -- <command>...runs the command in the dive environment instead of starting zsh. Plaindive <container>is unchanged.zsh -c), so arguments arrive intact, and it is passed through the sudo re-exec.kill,timeout, sudo relaying). Signals generated by the kernel (si_code > 0: Ctrl-C, terminal hangup) are not forwarded, since they already reach the command through the foreground process group.fork()read/proc/self/taskby path, which no longer resolves inside the container's mount namespace. Since fix: guard fork() sites against multi-threaded regressions #40 every session loggedcould not read /proc/self/task, and the check was skipped. It now keeps a handle on the original/proc. Includes a unit test.Testing
Local x86_64 tests with the 26.05 base image, against Alpine containers under Docker and rootless podman:
$; stdin and stdout piping/etc/os-release)NIX_SSL_CERT_FILEmatch the interactive shell; curl reaches github.com and rejects the eMudhra test hostuse_pty: the command gets exactly one SIGINT, and dive exits with its statustimeout -s TERM|INT|HUP 4 dive <ctr> -- sleep 47: the command is stopped after 4s. Before, Docker left it running (TERM) or waited the full duration (INT).Not tested: an interactive terminal session by hand.
Known limitation
si_codeshows who sent a signal, not who else received it. GNUtimeoutalso signals its whole process group. Under rootless podman that group signal reaches the command directly, on top of the copies relayed by sudo and dive:timeout -s INTdelivers SIGINT 3 times there. This is harmless for TERM/HUP, and only affects programs that treat a second Ctrl-C as "force quit". Under Docker only the relayed copy gets through, so it is delivered once. Fully deduplicating would require running the command in its own process group as the terminal's foreground job.🤖 Generated with Claude Code