(pid, options = {})
| 55 | } |
| 56 | |
| 57 | export function terminateProcessTree(pid, options = {}) { |
| 58 | if (!Number.isFinite(pid)) { |
| 59 | return { attempted: false, delivered: false, method: null }; |
| 60 | } |
| 61 | |
| 62 | const platform = options.platform ?? process.platform; |
| 63 | const runCommandImpl = options.runCommandImpl ?? runCommand; |
| 64 | const killImpl = options.killImpl ?? process.kill.bind(process); |
| 65 | |
| 66 | if (platform === "win32") { |
| 67 | const result = runCommandImpl("taskkill", ["/PID", String(pid), "/T", "/F"], { |
| 68 | cwd: options.cwd, |
| 69 | env: options.env |
| 70 | }); |
| 71 | |
| 72 | if (!result.error && result.status === 0) { |
| 73 | return { attempted: true, delivered: true, method: "taskkill", result }; |
| 74 | } |
| 75 | |
| 76 | const combinedOutput = `${result.stderr}\n${result.stdout}`.trim(); |
| 77 | if (!result.error && looksLikeMissingProcessMessage(combinedOutput)) { |
| 78 | return { attempted: true, delivered: false, method: "taskkill", result }; |
| 79 | } |
| 80 | |
| 81 | if (result.error?.code === "ENOENT") { |
| 82 | try { |
| 83 | killImpl(pid); |
| 84 | return { attempted: true, delivered: true, method: "kill" }; |
| 85 | } catch (error) { |
| 86 | if (error?.code === "ESRCH") { |
| 87 | return { attempted: true, delivered: false, method: "kill" }; |
| 88 | } |
| 89 | throw error; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | if (result.error) { |
| 94 | throw result.error; |
| 95 | } |
| 96 | |
| 97 | throw new Error(formatCommandFailure(result)); |
| 98 | } |
| 99 | |
| 100 | try { |
| 101 | killImpl(-pid, "SIGTERM"); |
| 102 | return { attempted: true, delivered: true, method: "process-group" }; |
| 103 | } catch (error) { |
| 104 | if (error?.code !== "ESRCH") { |
| 105 | try { |
| 106 | killImpl(pid, "SIGTERM"); |
| 107 | return { attempted: true, delivered: true, method: "process" }; |
| 108 | } catch (innerError) { |
| 109 | if (innerError?.code === "ESRCH") { |
| 110 | return { attempted: true, delivered: false, method: "process" }; |
| 111 | } |
| 112 | throw innerError; |
| 113 | } |
| 114 | } |
no test coverage detected