Files
rea/tests/fixtures/apktoolProcessTree.mjs
T

60 lines
1.8 KiB
JavaScript

import { spawn } from "node:child_process";
import { writeFileSync, renameSync } from "node:fs";
import { fileURLToPath } from "node:url";
const keepAlive = () => setInterval(() => {}, 1_000);
export const run = ({ mode, markerPath }) => {
const operation = process.argv[2];
if (mode === "decode" && operation === "--version") {
process.stdout.write("2.9.3\n");
return;
}
if (
(mode !== "probe" && mode !== "decode") ||
operation !== (mode === "probe" ? "--version" : "d")
)
throw new Error(`Unexpected Apktool fixture invocation: ${operation}`);
const runId = process.env.REA_PROCESS_RUN_ID;
if (typeof runId !== "string" || runId.length === 0)
throw new Error("Apktool fixture has no owned process run token");
if (mode === "decode") process.on("SIGTERM", () => {});
const child = spawn(
process.execPath,
[fileURLToPath(import.meta.url), "child", mode],
{
stdio: ["ignore", "inherit", "inherit", "ipc"],
},
);
const timer = keepAlive();
const publish = (ready) => {
if (child.pid === undefined) throw new Error("Fixture child has no PID");
const temporary = `${markerPath}.tmp`;
writeFileSync(
temporary,
JSON.stringify({
rootPid: process.pid,
childPid: child.pid,
runId,
ready,
}),
);
renameSync(temporary, markerPath);
};
child.once("spawn", () => publish(false));
child.on("message", (message) => {
if (message === "ready") publish(true);
});
child.once("error", (cause) => {
clearInterval(timer);
process.stderr.write(`${cause.message}\n`);
process.exitCode = 1;
});
};
if (process.argv[2] === "child") {
if (process.argv[3] === "decode") process.on("SIGTERM", () => {});
keepAlive();
process.send("ready");
}