mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-05 21:02:55 +00:00
Adds broad inline comments and JSDoc for CLI, cron, outbound/channel, plugin SDK, ACP, shared helpers, net policy, and related utility contracts. Proof: git diff --check on latest exact head plus focused cron tests passed; CI had no failing checks observed before merge attempt.
85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
import fsSync from "node:fs";
|
|
|
|
function isValidPid(pid: number): boolean {
|
|
return Number.isInteger(pid) && pid > 0;
|
|
}
|
|
|
|
/**
|
|
* Check if a process is a zombie on Linux by reading /proc/<pid>/status.
|
|
* Returns false on non-Linux platforms or if the proc file can't be read.
|
|
*/
|
|
function isZombieProcess(pid: number): boolean {
|
|
if (process.platform !== "linux") {
|
|
return false;
|
|
}
|
|
try {
|
|
const status = fsSync.readFileSync(`/proc/${pid}/status`, "utf8");
|
|
const stateMatch = status.match(/^State:\s+(\S)/m);
|
|
return stateMatch?.[1] === "Z";
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/** Returns true only when a positive PID exists and is not a Linux zombie process. */
|
|
export function isPidAlive(pid: number): boolean {
|
|
if (!isValidPid(pid)) {
|
|
return false;
|
|
}
|
|
try {
|
|
process.kill(pid, 0);
|
|
} catch {
|
|
return false;
|
|
}
|
|
if (isZombieProcess(pid)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/** Returns true only when the PID is invalid, missing, or known to be a Linux zombie. */
|
|
export function isPidDefinitelyDead(pid: number): boolean {
|
|
if (!isValidPid(pid)) {
|
|
return true;
|
|
}
|
|
try {
|
|
process.kill(pid, 0);
|
|
} catch (err) {
|
|
return (err as NodeJS.ErrnoException).code === "ESRCH";
|
|
}
|
|
return isZombieProcess(pid);
|
|
}
|
|
|
|
/**
|
|
* Read the process start time (field 22 "starttime") from /proc/<pid>/stat.
|
|
* Returns the value in clock ticks since system boot, or null on non-Linux
|
|
* platforms or if the proc file can't be read.
|
|
*
|
|
* This is used to detect PID recycling: if two readings for the same PID
|
|
* return different starttimes, the PID has been reused by a different process.
|
|
*/
|
|
export function getProcessStartTime(pid: number): number | null {
|
|
if (process.platform !== "linux") {
|
|
return null;
|
|
}
|
|
if (!isValidPid(pid)) {
|
|
return null;
|
|
}
|
|
try {
|
|
const stat = fsSync.readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
const commEndIndex = stat.lastIndexOf(")");
|
|
if (commEndIndex < 0) {
|
|
return null;
|
|
}
|
|
// The comm field (field 2) is wrapped in parens and can contain spaces,
|
|
// so split after the last ")" to get fields 3..N reliably.
|
|
const afterComm = stat.slice(commEndIndex + 1).trimStart();
|
|
const fields = afterComm.split(/\s+/);
|
|
// field 22 (starttime) = index 19 after the comm-split (field 3 is index 0).
|
|
const starttime = Number(fields[19]);
|
|
return Number.isInteger(starttime) && starttime >= 0 ? starttime : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|