diff --git a/src/run.ts b/src/run.ts index d7263dd..7725f02 100644 --- a/src/run.ts +++ b/src/run.ts @@ -28,6 +28,28 @@ type RunOptions = { onCommand?: (cmd: Command) => void } +function killTree(pid: number): void { + // Find any processes that escaped the process group (e.g. via setsid). + // This assumes pid === pgid, which holds because the child is spawned + // with detached: true (making it a process group leader). + try { + const result = Bun.spawnSync(["ps", "-eo", "pid,pgid"]) + const output = result.stdout.toString() + const pgid = String(pid) + for (const line of output.split("\n")) { + const parts = line.trim().split(/\s+/) + if (parts[1] === pgid) { + const p = parseInt(parts[0]!, 10) + if (!isNaN(p) && p !== pid && p > 1) { + try { process.kill(p, "SIGKILL") } catch {} + } + } + } + } catch {} + // Kill the process group + try { process.kill(-pid, "SIGKILL") } catch {} +} + const SENTINEL_PREFIX = "__SHOUT_SENTINEL_" const VERBOSE_MARKER = "__SHOUT_CMD_" @@ -235,7 +257,7 @@ export async function runFile( } } finally { if (proc.pid) { - try { process.kill(-proc.pid, "SIGKILL") } catch {} + killTree(proc.pid) } } }