UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

81 lines (80 loc) • 3.43 kB
import { t as hasErrnoCode } from "./errno-jiy5vtf-.mjs"; import { i as isPidDefinitelyDead } from "./pid-alive-Cnn-Mjdg.mjs"; import { t as inspectOtherOpenClawProcesses } from "./openclaw-process-census-DpYyGSsZ.mjs"; import fsSync from "node:fs"; //#region src/infra/temp-directory-usage.ts /** Tokenless scratch needs both producer and open-file evidence before reclamation. */ function inspectTemporaryDirectoryUsage(directory) { if (process.platform === "linux") try { const [mount, ...otherMounts] = fsSync.readFileSync("/proc/self/mountinfo", "utf8").split("\n").map((line) => line.split(" ")).filter((fields) => fields[4] === "/proc"); const separator = mount?.indexOf("-") ?? -1; if (!mount || otherMounts.length > 0 || separator < 6 || mount[separator + 1] !== "proc" || !mount[5] || !mount[separator + 3]) throw new Error("Procfs mount information is incomplete or ambiguous."); if (`${mount[5]},${mount[separator + 3]}`.split(",").some((option) => option === "subset=pid" || option.startsWith("hidepid=") && option !== "hidepid=0" && option !== "hidepid=off")) return { kind: "unknown", reason: "restricted-procfs" }; } catch (error) { return { kind: "unknown", reason: `Could not inspect procfs visibility: ${String(error)}` }; } const census = inspectOtherOpenClawProcesses(); if ("error" in census) return { kind: "unknown", reason: census.error }; if (census.pids.length > 0) return { kind: "active" }; if (process.platform !== "linux") return { kind: "unknown", reason: `Open-file census is unavailable on ${process.platform}.` }; const contains = (target) => { const file = target.replace(/ \(deleted\)$/, ""); return file === directory || file.startsWith(`${directory}/`); }; const deadline = performance.now() + 1e3; const assertTime = () => { if (performance.now() >= deadline) throw new Error("Open-file census exceeded its deadline."); }; try { const pids = fsSync.readdirSync("/proc").filter((name) => /^\d+$/.test(name)); if (!pids.includes(String(process.pid))) throw new Error("Open-file census is incomplete."); for (const pid of pids) { assertTime(); try { for (const fd of fsSync.readdirSync(`/proc/${pid}/fd`)) { assertTime(); try { if (contains(fsSync.readlinkSync(`/proc/${pid}/fd/${fd}`))) return { kind: "active" }; } catch (error) { if (!hasErrnoCode(error, "ENOENT")) throw error; } } const maps = fsSync.readFileSync(`/proc/${pid}/maps`, "utf8"); for (const line of maps.split("\n")) { const file = /^\S+\s+\S+\s+\S+\s+\S+\s+\d+\s+(\/.*)$/.exec(line)?.[1]; if (file && contains(file.replace(/\\([0-7]{3})/g, (_, octal) => String.fromCharCode(Number.parseInt(octal, 8))))) return { kind: "active" }; } try { if (contains(fsSync.readlinkSync(`/proc/${pid}/cwd`))) return { kind: "active" }; } catch (error) { const stat = fsSync.readFileSync(`/proc/${pid}/stat`, "utf8"); const flags = Number(stat.slice(stat.lastIndexOf(")") + 2).split(/\s+/)[6]); if (!hasErrnoCode(error, "ENOENT") || (flags & 2097152) === 0) throw error; } } catch (error) { if (!isPidDefinitelyDead(Number(pid))) throw error; } } assertTime(); return { kind: "inactive" }; } catch (error) { return { kind: "unknown", reason: `Could not inspect open files: ${String(error)}` }; } } //#endregion export { inspectTemporaryDirectoryUsage };