console start and stop move a console.json whose recorded process is gone aside instead of refusing (P19 #857). mosaic org lock show|clear reports a lifecycle lock holder and clears it only when the holder is dead. mosaic bus recover marks a bus host stopped when its process is gone and its socket does not answer, and writes a recovery receipt (P19 #862).
19 lines
1.0 KiB
JavaScript
19 lines
1.0 KiB
JavaScript
// Read process identity without treating an unreadable /proc entry as death.
|
|
import { readFileSync } from 'node:fs';
|
|
export function processState(pid) {
|
|
if (!Number.isSafeInteger(pid) || pid <= 0) throw new Error('invalid pid');
|
|
let raw;
|
|
try { raw = readFileSync(`/proc/${pid}/stat`, 'utf8'); }
|
|
catch (e) {
|
|
if (e.code !== 'ENOENT' && e.code !== 'ESRCH') throw e;
|
|
// Signal zero only probes existence; it delivers no signal. A missing or
|
|
// restricted proc mount must never make a live process appear dead.
|
|
try { process.kill(pid, 0); } catch (probe) { if (probe.code === 'ESRCH') return { alive: false }; throw probe; }
|
|
throw new Error('process exists but proc identity is unavailable');
|
|
}
|
|
const end = raw.lastIndexOf(')');
|
|
const fields = raw.slice(end + 2).trim().split(/\s+/);
|
|
if (end < 0 || fields.length < 20 || !/^\d+$/.test(fields[19])) throw new Error('unreadable process identity');
|
|
return fields[0] === 'Z' || fields[0] === 'X' ? { alive: false } : { alive: true, startTime: fields[19] };
|
|
}
|