Skip to content

Commit 34a19a5

Browse files
author
Codex
committed
Fix Windows proxy stop verification
1 parent 62edb7b commit 34a19a5

1 file changed

Lines changed: 33 additions & 5 deletions

File tree

src/cli.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env bun
2+
import { execFileSync } from "node:child_process";
23
import { restoreNativeCodex } from "./codex-inject";
34
import { loadConfig, readPid, removePid, writePid } from "./config";
45
import { serviceCommand } from "./service";
@@ -88,32 +89,59 @@ function handleStart() {
8889
}
8990

9091
function killProxy(pid: number): void {
92+
if (!isProcessAlive(pid)) return;
9193
if (process.platform === "win32") {
94+
const taskkill = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\taskkill.exe`;
9295
try {
93-
(require("node:child_process") as typeof import("node:child_process"))
94-
.execSync(`taskkill /PID ${pid} /T /F`, { stdio: "pipe" });
95-
} catch { /* process already gone */ }
96+
execFileSync(taskkill, ["/PID", String(pid), "/T", "/F"], { stdio: "pipe" });
97+
} catch (err) {
98+
if (isProcessAlive(pid)) throw err;
99+
}
96100
} else {
97101
process.kill(pid, "SIGTERM");
102+
if (!waitForExit(pid, 5000)) process.kill(pid, "SIGKILL");
103+
}
104+
if (!waitForExit(pid, 5000)) throw new Error(`process ${pid} did not exit`);
105+
}
106+
107+
function isProcessAlive(pid: number): boolean {
108+
try {
109+
process.kill(pid, 0);
110+
return true;
111+
} catch {
112+
return false;
98113
}
99114
}
100115

116+
function waitForExit(pid: number, timeoutMs: number): boolean {
117+
const deadline = Date.now() + timeoutMs;
118+
const marker = new Int32Array(new SharedArrayBuffer(4));
119+
while (Date.now() < deadline) {
120+
if (!isProcessAlive(pid)) return true;
121+
Atomics.wait(marker, 0, 0, 50);
122+
}
123+
return !isProcessAlive(pid);
124+
}
125+
101126
function handleStop() {
102127
const pid = readPid();
128+
let stopFailed = false;
103129
if (pid) {
104130
try {
105131
killProxy(pid);
106132
console.log(`✅ Proxy (PID ${pid}) stopped.`);
133+
removePid();
107134
} catch {
108-
console.log("Proxy process not found.");
135+
stopFailed = true;
136+
console.error(`❌ Failed to stop proxy (PID ${pid}).`);
109137
}
110-
removePid();
111138
} else {
112139
console.log("No running proxy found.");
113140
}
114141
// Recover native Codex so plain `codex` keeps working while the proxy is down.
115142
const r = restoreNativeCodex();
116143
console.log(`↩️ ${r.message}`);
144+
if (stopFailed) process.exit(1);
117145
}
118146

119147
function handleStatus() {

0 commit comments

Comments
 (0)