mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-03 08:58:23 +08:00
40 lines
1.6 KiB
JavaScript
40 lines
1.6 KiB
JavaScript
export const MAX_INLINE_SANDBOX_COMMAND_BYTES = 768;
|
|
// Outside the shell exit-code range, so an actual exit 125 stays a failure.
|
|
export const REMOTE_COMMAND_PENDING = 256;
|
|
|
|
export const shellQuote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
|
|
/** Keep long shell programs out of the local CLI's argument vector. The
|
|
* same script records the remote exit status for either transport. */
|
|
export function sandboxCommand(command, args, exitMarker) {
|
|
const statusPath = `/tmp/${exitMarker}.status`;
|
|
const script =
|
|
`${[command, ...args].map(shellQuote).join(" ")}; scriptc_status=$?; ` +
|
|
`printf '%s\\n' "$scriptc_status" > ${shellQuote(statusPath)}; ` +
|
|
`printf '\\n${exitMarker}%s\\n' "$scriptc_status"`;
|
|
const scriptPath = `/tmp/${exitMarker}.sh`;
|
|
const file = Buffer.byteLength(script, "utf8") > MAX_INLINE_SANDBOX_COMMAND_BYTES;
|
|
return {
|
|
script,
|
|
scriptPath,
|
|
statusPath,
|
|
file,
|
|
argv: file ? ["sh", scriptPath] : ["sh", "-c", script],
|
|
};
|
|
}
|
|
|
|
/** Allow a disconnected command to finish before probing its recorded exit. */
|
|
export function sandboxStatusCommand(statusPath, exitMarker, waitSeconds = 20) {
|
|
if (!Number.isSafeInteger(waitSeconds) || waitSeconds < 0) {
|
|
throw new Error("status wait must be a nonnegative integer");
|
|
}
|
|
return (
|
|
`scriptc_wait=${waitSeconds}; ` +
|
|
`while test ! -s ${shellQuote(statusPath)} && test "$scriptc_wait" -gt 0; do ` +
|
|
`sleep 1; scriptc_wait=$((scriptc_wait - 1)); done; ` +
|
|
`scriptc_status=${REMOTE_COMMAND_PENDING}; test ! -s ${shellQuote(statusPath)} || ` +
|
|
`scriptc_status=$(cat ${shellQuote(statusPath)}); ` +
|
|
`printf '\\n${exitMarker}%s\\n' "$scriptc_status"`
|
|
);
|
|
}
|