* Kills a process and all its descendants. * Signals are sent synchronously (children first) to work in exit handlers, * then waits asynchronously for processes to die.
(pid: number, force: boolean)
| 94 | * then waits asynchronously for processes to die. |
| 95 | */ |
| 96 | async function killProcessTree(pid: number, force: boolean): Promise<boolean> { |
| 97 | // Collect all PIDs first (sync) - returns in child-first order |
| 98 | const pids = collectProcessTree(pid); |
| 99 | |
| 100 | // Signal all processes synchronously (children first, then root) |
| 101 | const signal = force ? 'SIGKILL' : 'SIGTERM'; |
| 102 | for (const p of pids) { |
| 103 | try { |
| 104 | process.kill(p, signal); |
| 105 | } catch { |
| 106 | // Process may have already exited |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // Wait for processes to die (async) - wait for root last |
| 111 | for (const p of pids) { |
| 112 | await waitForProcessToDie(p, force); |
| 113 | } |
| 114 | |
| 115 | return true; |
| 116 | } |
| 117 | |
| 118 | /** |
| 119 | * Waits for a process to die, escalating to SIGKILL if SIGTERM doesn't work. |
no test coverage detected