fix(v03): forward sigterm from env reuse launcher (#2002)

This commit is contained in:
Lyon
2026-06-24 01:43:34 +08:00
committed by GitHub
parent f7db5e7cc2
commit 8a382d45ae
@@ -1,4 +1,4 @@
import { spawnSync } from "node:child_process";
import { spawn, spawnSync } from "node:child_process";
import { chmodSync, existsSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import path from "node:path";
@@ -89,6 +89,10 @@ function installHwpodAlias(commandName: string, relativeCli: string): void {
}
function run(command: string, args: string[], cwd: string, options: { replace?: boolean } = {}): void {
if (options.replace) {
runReplacingProcess(command, args, cwd);
return;
}
const result = spawnSync(command, args, {
cwd,
env: process.env,
@@ -97,10 +101,56 @@ function run(command: string, args: string[], cwd: string, options: { replace?:
if (result.error) fail(`${command} failed to start: ${result.error.message}`);
if (result.signal) process.kill(process.pid, result.signal);
const code = result.status ?? 0;
if (options.replace) process.exit(code);
if (code !== 0) process.exit(code);
}
function runReplacingProcess(command: string, args: string[], cwd: string): void {
const child = spawn(command, args, {
cwd,
env: process.env,
stdio: "inherit",
detached: true
});
let settled = false;
const signalHandlers: Array<{ signal: string, handler: () => void }> = [];
const cleanup = () => {
for (const { signal, handler } of signalHandlers.splice(0)) {
process.off(signal, handler);
}
};
const forwardSignal = (signal: string) => {
if (!child.pid) return;
try {
process.kill(-child.pid, signal);
} catch {
try { child.kill(signal); } catch {}
}
};
for (const signal of ["SIGINT", "SIGTERM"]) {
const handler = () => forwardSignal(signal);
process.on(signal, handler);
signalHandlers.push({ signal, handler });
}
child.on("error", (error) => {
if (settled) return;
settled = true;
cleanup();
fail(`${command} failed to start: ${error.message}`);
});
child.on("exit", (code, signal) => {
if (settled) return;
settled = true;
cleanup();
if (signal) process.exit(signalExitCode(signal));
process.exit(code ?? 0);
});
}
function signalExitCode(signal: string): number {
const signals: Record<string, number> = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGTERM: 15 };
return 128 + (signals[signal] ?? 1);
}
function fail(message: string): never {
process.stderr.write(`${JSON.stringify({ status: "failed", error: "hwlab_env_reuse_launcher_failed", message })}\n`);
process.exit(1);