diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 21:05:37 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | bc63a8f38a837d4b0a65d86ccf5f956fc6ff6d83 (patch) | |
| tree | 548b9ce43a7718230d447cb316fcfa3c16685538 | |
| parent | 0fd908eea63d04886b269438aa7529d3dd422256 (diff) | |
| download | pardes-bc63a8f38a837d4b0a65d86ccf5f956fc6ff6d83.tar.gz pardes-bc63a8f38a837d4b0a65d86ccf5f956fc6ff6d83.zip | |
Kill stops a command's shell before its jobs, so the line never runs on to its next command in between
signalTty signalled the running job's group first, then scanned all of
/proc for the session's & jobs, then the shell. A job dead of the signal
lets a job-control shell run the line's next command, and once pids wrap
below the host's older processes the scan takes long enough for it to:
"sleep 0.4; touch killed" killed at 150ms touched the file. The host_io
test caught it every run after the pids wrapped (pid_max 4194304, new pids
near 17000, 229 older processes above them to scan). The shell's group now
goes first, then the session's groups, then the foreground one.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/host_io.zig | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/host_io.zig b/src/host_io.zig index 9e3fbf79..eb6d1d5d 100644 --- a/src/host_io.zig +++ b/src/host_io.zig @@ -1917,6 +1917,9 @@ fn reapShell(pid: libc.pid_t, grace_ms: u32) void { /// the rest of the line would run on after the job it was on. A stop (TERM /// or KILL) of a command reaches its `&` jobs too, each in a group of its /// own in the shell's session: Kill leaves nothing the line started. +/// The shell goes first: a job that died before it would let it run the +/// line's next command in the gap, and the gap is a scan of all of /proc +/// (signalSession), long once pids have wrapped below the old processes'. pub fn signalTty(shell_pid: libc.pid_t, master_fd: c_int, which: pardes.PtySignal, command: bool) void { const sig = switch (which) { .int => libc.SIG.INT, @@ -1926,9 +1929,9 @@ pub fn signalTty(shell_pid: libc.pid_t, master_fd: c_int, which: pardes.PtySigna .kill => libc.SIG.KILL, }; const fg = tcgetpgrp(master_fd); + if (command and shell_pid > 0 and fg != shell_pid) _ = libc.kill(-shell_pid, sig); if (command and shell_pid > 0 and (which == .term or which == .kill)) signalSession(shell_pid, sig); if (fg > 0) _ = libc.kill(-fg, sig); - if (command and shell_pid > 0 and fg != shell_pid) _ = libc.kill(-shell_pid, sig); if (fg <= 0 and !command and shell_pid > 0) _ = libc.kill(shell_pid, sig); } |
