openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
81 lines (80 loc) • 3.43 kB
JavaScript
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 };