Files
dbx/plugins/sdk/dev-host/process-tree.mjs

33 lines
1.0 KiB
JavaScript

import { spawn } from "node:child_process";
import { setTimeout as delay } from "node:timers/promises";
// Unix children must be spawned detached so their process group belongs to us.
export async function stopProcessTree(child) {
if (!child?.pid) return;
if (process.platform === "win32") {
await new Promise((resolve) => {
const killer = spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], { stdio: "ignore" });
killer.once("error", resolve);
killer.once("close", resolve);
});
return;
}
const signal = (value) => {
try {
process.kill(-child.pid, value);
return true;
} catch (error) {
// macOS can return EPERM for a group containing only reparented zombies.
if (error.code === "ESRCH" || (value === 0 && error.code === "EPERM")) return false;
throw error;
}
};
if (!signal("SIGTERM")) return;
// A leader exiting does not imply that its descendants have exited.
for (let i = 0; i < 40; i++) {
await delay(50);
if (!signal(0)) return;
}
signal("SIGKILL");
}