@ai-ecoverse/slicc-kernel 1.174.2 → 1.175.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +212 -9
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +212 -9
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/kernel/process.d.ts +1 -0
- package/dist/types/kernel/sealed.d.ts +21 -2
- package/dist/types/launcher.d.ts +4 -0
- package/dist/types/node.d.ts +1 -1
- package/dist/types/sealed-command.d.ts +4 -0
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -8740,7 +8740,7 @@ function satisfies(version, range2) {
|
|
|
8740
8740
|
}
|
|
8741
8741
|
|
|
8742
8742
|
// src/version.ts
|
|
8743
|
-
var KERNEL_VERSION = true ? "1.
|
|
8743
|
+
var KERNEL_VERSION = true ? "1.175.0" : "0.0.0-dev";
|
|
8744
8744
|
var OS_RELEASE = "6.0.0-slicc";
|
|
8745
8745
|
function procVersion() {
|
|
8746
8746
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -19063,7 +19063,12 @@ function sessionValues(reply, asked) {
|
|
|
19063
19063
|
// src/kernel/sealed.ts
|
|
19064
19064
|
var SEALED_MAX_BYTES = 64 * 1024;
|
|
19065
19065
|
var SEALED_TIMEOUT_MS = 1e4;
|
|
19066
|
+
var SEALED_ASK_TIMEOUT_MS = 305e3;
|
|
19067
|
+
var SEALED_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
19068
|
+
var SEALED_NAME_MAX = 128;
|
|
19069
|
+
var SEALED_PROMPT_MAX = 200;
|
|
19066
19070
|
var SEALED_OPS = /* @__PURE__ */ new Set([
|
|
19071
|
+
"ask",
|
|
19067
19072
|
"seal",
|
|
19068
19073
|
"placeholder",
|
|
19069
19074
|
"list",
|
|
@@ -19078,6 +19083,16 @@ function tagFields(tags) {
|
|
|
19078
19083
|
if (tag === void 0) return {};
|
|
19079
19084
|
return tags.length > 1 ? { tag, tags: [...tags] } : { tag };
|
|
19080
19085
|
}
|
|
19086
|
+
var ASK_FIELDS = /* @__PURE__ */ new Set([
|
|
19087
|
+
"v",
|
|
19088
|
+
"op",
|
|
19089
|
+
"name",
|
|
19090
|
+
"prompt",
|
|
19091
|
+
"reveal",
|
|
19092
|
+
"replace",
|
|
19093
|
+
"caller",
|
|
19094
|
+
"requester"
|
|
19095
|
+
]);
|
|
19081
19096
|
var encoder6 = new TextEncoder();
|
|
19082
19097
|
var decoder3 = new TextDecoder("utf-8", { fatal: true });
|
|
19083
19098
|
function parseSealed(bytes) {
|
|
@@ -19095,6 +19110,7 @@ function parseSealed(bytes) {
|
|
|
19095
19110
|
if (req.v !== 1 || typeof req.op !== "string" || !SEALED_OPS.has(req.op))
|
|
19096
19111
|
throw new KernelError("EINVAL");
|
|
19097
19112
|
if (req.op === "materialize" && !materializable(req)) throw new KernelError("EINVAL");
|
|
19113
|
+
if (req.op === "ask" && !askable(req)) throw new KernelError("EINVAL");
|
|
19098
19114
|
return req;
|
|
19099
19115
|
} finally {
|
|
19100
19116
|
bytes.fill(0);
|
|
@@ -19104,6 +19120,27 @@ function materializable(req) {
|
|
|
19104
19120
|
if (req.shellGrants !== true && !isStrings(req.names)) return false;
|
|
19105
19121
|
return isStrings(req.argv) && typeof req.path === "string" && typeof req.cwd === "string";
|
|
19106
19122
|
}
|
|
19123
|
+
function askable(req) {
|
|
19124
|
+
if (Object.keys(req).some((key) => !ASK_FIELDS.has(key))) return false;
|
|
19125
|
+
const { name: name2, prompt, reveal, replace } = req;
|
|
19126
|
+
if (typeof name2 !== "string" || name2.length > SEALED_NAME_MAX || !SEALED_NAME.test(name2))
|
|
19127
|
+
return false;
|
|
19128
|
+
if (prompt !== void 0 && (typeof prompt !== "string" || [...prompt].length > SEALED_PROMPT_MAX))
|
|
19129
|
+
return false;
|
|
19130
|
+
return [reveal, replace].every((flag) => flag === void 0 || typeof flag === "boolean");
|
|
19131
|
+
}
|
|
19132
|
+
function askRequest(fields, caller, requester) {
|
|
19133
|
+
return {
|
|
19134
|
+
v: 1,
|
|
19135
|
+
op: "ask",
|
|
19136
|
+
name: fields.name,
|
|
19137
|
+
...fields.prompt !== void 0 ? { prompt: fields.prompt } : {},
|
|
19138
|
+
reveal: fields.reveal === true,
|
|
19139
|
+
replace: fields.replace === true,
|
|
19140
|
+
caller,
|
|
19141
|
+
requester
|
|
19142
|
+
};
|
|
19143
|
+
}
|
|
19107
19144
|
function errorReply(code, message3) {
|
|
19108
19145
|
return { v: 1, error: { code, message: message3 } };
|
|
19109
19146
|
}
|
|
@@ -19136,7 +19173,7 @@ var SealedChannel = class {
|
|
|
19136
19173
|
this.broker = broker;
|
|
19137
19174
|
this.access = access2;
|
|
19138
19175
|
}
|
|
19139
|
-
send(bytes, caller, gone) {
|
|
19176
|
+
send(bytes, caller, gone, requester = async () => void 0) {
|
|
19140
19177
|
if (this.access === "read") {
|
|
19141
19178
|
bytes.fill(0);
|
|
19142
19179
|
throw new KernelError("EBADF");
|
|
@@ -19149,10 +19186,15 @@ var SealedChannel = class {
|
|
|
19149
19186
|
const withdraw = () => control.abort("withdrawn");
|
|
19150
19187
|
if (gone.aborted) withdraw();
|
|
19151
19188
|
else gone.addEventListener("abort", withdraw, { once: true });
|
|
19152
|
-
const
|
|
19189
|
+
const ask = fields.op === "ask";
|
|
19190
|
+
const timer = setTimeout(
|
|
19191
|
+
() => control.abort(ask ? "expired" : "timeout"),
|
|
19192
|
+
ask ? this.broker.askTimeoutMs : this.broker.timeoutMs
|
|
19193
|
+
);
|
|
19153
19194
|
const req = { ...fields, v: 1, op: fields.op, caller };
|
|
19195
|
+
const asked = ask ? this.asking(fields, caller, requester, control.signal) : void 0;
|
|
19154
19196
|
const flight = { control, done: Promise.resolve() };
|
|
19155
|
-
flight.done = this.answer(req, control.signal).then(async (reply) => {
|
|
19197
|
+
flight.done = (asked ?? this.answer(req, control.signal)).then(async (reply) => {
|
|
19156
19198
|
clearTimeout(timer);
|
|
19157
19199
|
gone.removeEventListener("abort", withdraw);
|
|
19158
19200
|
if (reply && req.op === "materialize")
|
|
@@ -19164,6 +19206,17 @@ var SealedChannel = class {
|
|
|
19164
19206
|
this.inflight = flight;
|
|
19165
19207
|
return length2;
|
|
19166
19208
|
}
|
|
19209
|
+
async asking(fields, caller, requester, signal) {
|
|
19210
|
+
const facts = await requester().catch(() => void 0);
|
|
19211
|
+
if (signal.aborted) return this.stopped(signal);
|
|
19212
|
+
if (!facts) return errorReply("EIO", "the kernel has no record of this process");
|
|
19213
|
+
return this.answer(askRequest(fields, caller, facts), signal);
|
|
19214
|
+
}
|
|
19215
|
+
stopped(signal) {
|
|
19216
|
+
if (signal.reason === "timeout")
|
|
19217
|
+
return errorReply("ETIMEDOUT", "the vault did not answer within 10 s");
|
|
19218
|
+
return signal.reason === "expired" ? { v: 1, state: "expired" } : void 0;
|
|
19219
|
+
}
|
|
19167
19220
|
async answer(req, signal) {
|
|
19168
19221
|
const hook = this.broker.hook;
|
|
19169
19222
|
if (!hook) return errorReply("ENOTCONN", "no vault is connected");
|
|
@@ -19176,8 +19229,7 @@ var SealedChannel = class {
|
|
|
19176
19229
|
(err) => errorReply("EIO", lineOf3(err))
|
|
19177
19230
|
);
|
|
19178
19231
|
const reply = await Promise.race([asked, stopped]);
|
|
19179
|
-
|
|
19180
|
-
return signal.reason === "timeout" ? errorReply("ETIMEDOUT", "the vault did not answer within 10 s") : void 0;
|
|
19232
|
+
return signal.aborted ? this.stopped(signal) : reply;
|
|
19181
19233
|
}
|
|
19182
19234
|
drop() {
|
|
19183
19235
|
this.reply?.fill(0);
|
|
@@ -19239,7 +19291,9 @@ var SealedBroker = class {
|
|
|
19239
19291
|
tagOf;
|
|
19240
19292
|
tickets = new TicketBook();
|
|
19241
19293
|
sessions = new SessionScrubs();
|
|
19294
|
+
askTimeoutMs = SEALED_ASK_TIMEOUT_MS;
|
|
19242
19295
|
userOf = async () => void 0;
|
|
19296
|
+
factsOf = async () => void 0;
|
|
19243
19297
|
constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
|
|
19244
19298
|
this.hook = hook;
|
|
19245
19299
|
this.users = users;
|
|
@@ -27626,7 +27680,10 @@ var WasmProcess = class {
|
|
|
27626
27680
|
}
|
|
27627
27681
|
async write(fd, body, nonblock = false, cancelled) {
|
|
27628
27682
|
const file = this.fds.get(fd).file;
|
|
27629
|
-
if (file.sealed)
|
|
27683
|
+
if (file.sealed) {
|
|
27684
|
+
const caller = await this.sealedCaller();
|
|
27685
|
+
return file.sealed.send(body, caller, this.gone.signal, () => this.sealedRequester());
|
|
27686
|
+
}
|
|
27630
27687
|
if (!file.write) throw new KernelError("EBADF");
|
|
27631
27688
|
if (file.embedder) return this.writeEmbedder(file, body, nonblock, cancelled);
|
|
27632
27689
|
if (!pollFile(file).writable) {
|
|
@@ -27831,6 +27888,10 @@ var WasmProcess = class {
|
|
|
27831
27888
|
const ids = { pid: shown2?.pid ?? this.pid, ppid: shown2?.ppid ?? 0 };
|
|
27832
27889
|
return broker.stamp(ids, this.cred, broker.tagOf(this.pid));
|
|
27833
27890
|
}
|
|
27891
|
+
async sealedRequester() {
|
|
27892
|
+
const facts = await this.options.sealed.factsOf(this.pid);
|
|
27893
|
+
return facts && { ...facts, stdin: this.stdinKind() };
|
|
27894
|
+
}
|
|
27834
27895
|
guarded() {
|
|
27835
27896
|
const { guard: guard2 } = this.options;
|
|
27836
27897
|
return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid, links: guard2.links };
|
|
@@ -32738,6 +32799,122 @@ function refusing(command) {
|
|
|
32738
32799
|
};
|
|
32739
32800
|
}
|
|
32740
32801
|
|
|
32802
|
+
// src/sealed-command.ts
|
|
32803
|
+
var SEALED_BIN = "/usr/bin/sealed";
|
|
32804
|
+
var SEALED_COMMAND = {
|
|
32805
|
+
name: "sealed",
|
|
32806
|
+
abi: "js",
|
|
32807
|
+
glue: SEALED_BIN,
|
|
32808
|
+
wasm: SEALED_BIN,
|
|
32809
|
+
argv0: "sealed"
|
|
32810
|
+
};
|
|
32811
|
+
var SEALED_SOURCE = `export default async function sealed(ctx) {
|
|
32812
|
+
const USAGE = "usage: sealed ask NAME [--prompt TEXT] [--reveal] [--replace]\\n sealed placeholder NAME\\n sealed list [--json]\\n";
|
|
32813
|
+
const NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
32814
|
+
const EXIT = { EINVAL: 2, EACCES: 3, EAGAIN: 4, ETIMEDOUT: 124 };
|
|
32815
|
+
const say = (fd, text) => ctx.write(fd, text).catch(() => undefined);
|
|
32816
|
+
const fail = async (status, text) => {
|
|
32817
|
+
await say(2, "sealed: " + text + "\\n");
|
|
32818
|
+
return status;
|
|
32819
|
+
};
|
|
32820
|
+
const usage = async (text) => {
|
|
32821
|
+
if (text !== undefined) await say(2, "sealed: " + text + "\\n");
|
|
32822
|
+
await say(2, USAGE);
|
|
32823
|
+
return 2;
|
|
32824
|
+
};
|
|
32825
|
+
const [action, ...args] = ctx.argv.slice(1);
|
|
32826
|
+
if (action === undefined || action === "-h" || action === "--help") return usage();
|
|
32827
|
+
let name;
|
|
32828
|
+
let prompt;
|
|
32829
|
+
let reveal = false;
|
|
32830
|
+
let replace = false;
|
|
32831
|
+
let asJson = false;
|
|
32832
|
+
for (let i = 0; i < args.length; i++) {
|
|
32833
|
+
const arg = args[i];
|
|
32834
|
+
if (action === "ask" && arg === "--prompt") {
|
|
32835
|
+
prompt = args[++i];
|
|
32836
|
+
if (prompt === undefined) return usage("--prompt needs a text");
|
|
32837
|
+
} else if (action === "ask" && arg.startsWith("--prompt=")) prompt = arg.slice(9);
|
|
32838
|
+
else if (action === "ask" && arg === "--reveal") reveal = true;
|
|
32839
|
+
else if (action === "ask" && arg === "--replace") replace = true;
|
|
32840
|
+
else if (action === "list" && arg === "--json") asJson = true;
|
|
32841
|
+
else if (action !== "list" && name === undefined && !arg.startsWith("-")) name = arg;
|
|
32842
|
+
else return usage("unexpected argument " + JSON.stringify(arg));
|
|
32843
|
+
}
|
|
32844
|
+
let request;
|
|
32845
|
+
if (action === "ask" || action === "placeholder") {
|
|
32846
|
+
if (name === undefined) return usage("a NAME is needed");
|
|
32847
|
+
if (name.length > 128 || !NAME.test(name)) return fail(2, JSON.stringify(name) + " is not a valid name");
|
|
32848
|
+
if (prompt !== undefined && [...prompt].length > 200) return fail(2, "the prompt is longer than 200 characters");
|
|
32849
|
+
request = action === "ask"
|
|
32850
|
+
? { v: 1, op: "ask", name, ...(prompt !== undefined ? { prompt } : {}), reveal, replace }
|
|
32851
|
+
: { v: 1, op: "placeholder", name };
|
|
32852
|
+
} else if (action === "list") request = { v: 1, op: "list" };
|
|
32853
|
+
else return usage("unknown command " + JSON.stringify(action));
|
|
32854
|
+
let reply;
|
|
32855
|
+
try {
|
|
32856
|
+
reply = await exchange(request);
|
|
32857
|
+
} catch (err) {
|
|
32858
|
+
const code = err && err.code ? err.code : String(err);
|
|
32859
|
+
return fail(EXIT[code] ?? 1, "/dev/sealed: " + code);
|
|
32860
|
+
}
|
|
32861
|
+
if (reply.error !== undefined) {
|
|
32862
|
+
const code = String(reply.error && reply.error.code);
|
|
32863
|
+
const message = reply.error && reply.error.message ? reply.error.message : code;
|
|
32864
|
+
return fail(EXIT[code] ?? 1, (name !== undefined ? name + ": " : "") + message);
|
|
32865
|
+
}
|
|
32866
|
+
const newline = (await ctx.isatty(1).catch(() => false)) ? "\\n" : "";
|
|
32867
|
+
if (action === "list") {
|
|
32868
|
+
const secrets = Array.isArray(reply.secrets) ? reply.secrets : [];
|
|
32869
|
+
if (asJson) {
|
|
32870
|
+
await say(1, JSON.stringify(secrets) + "\\n");
|
|
32871
|
+
return 0;
|
|
32872
|
+
}
|
|
32873
|
+
await say(1, secrets.map((s) => s.name + "\\t" + s.placeholder + "\\t" + s.state + "\\n").join(""));
|
|
32874
|
+
return 0;
|
|
32875
|
+
}
|
|
32876
|
+
if (action === "placeholder") {
|
|
32877
|
+
if (typeof reply.placeholder !== "string") return fail(1, name + ": the vault gave no placeholder");
|
|
32878
|
+
await say(1, reply.placeholder + newline);
|
|
32879
|
+
return 0;
|
|
32880
|
+
}
|
|
32881
|
+
if (reply.state === "cancelled") return fail(1, name + ": cancelled");
|
|
32882
|
+
if (reply.state === "expired") return fail(124, name + ": the request expired");
|
|
32883
|
+
if (reply.state !== "done") return fail(1, name + ": the vault gave no answer");
|
|
32884
|
+
const out = reveal ? reply.value : reply.placeholder;
|
|
32885
|
+
if (typeof out !== "string") return fail(1, name + ": the vault gave no " + (reveal ? "value" : "placeholder"));
|
|
32886
|
+
await say(1, out + newline);
|
|
32887
|
+
return 0;
|
|
32888
|
+
|
|
32889
|
+
async function exchange(req) {
|
|
32890
|
+
const file = await ctx.open("/dev/sealed", { read: true, write: true });
|
|
32891
|
+
try {
|
|
32892
|
+
await ctx.write(file.fd, JSON.stringify(req));
|
|
32893
|
+
const parts = [];
|
|
32894
|
+
for (;;) {
|
|
32895
|
+
const chunk = await ctx.read(file.fd, 65536);
|
|
32896
|
+
if (chunk.length === 0) break;
|
|
32897
|
+
parts.push(chunk);
|
|
32898
|
+
}
|
|
32899
|
+
const bytes = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
|
|
32900
|
+
let at = 0;
|
|
32901
|
+
for (const part of parts) {
|
|
32902
|
+
bytes.set(part, at);
|
|
32903
|
+
at += part.length;
|
|
32904
|
+
part.fill(0);
|
|
32905
|
+
}
|
|
32906
|
+
const text = new TextDecoder().decode(bytes);
|
|
32907
|
+
bytes.fill(0);
|
|
32908
|
+
const parsed = JSON.parse(text);
|
|
32909
|
+
if (typeof parsed !== "object" || parsed === null) throw Object.assign(new Error("EIO"), { code: "EIO" });
|
|
32910
|
+
return parsed;
|
|
32911
|
+
} finally {
|
|
32912
|
+
await file.close().catch(() => undefined);
|
|
32913
|
+
}
|
|
32914
|
+
}
|
|
32915
|
+
}
|
|
32916
|
+
`;
|
|
32917
|
+
|
|
32741
32918
|
// src/sudo-command.ts
|
|
32742
32919
|
var SUDO_PATH = "/usr/bin/sudo";
|
|
32743
32920
|
var SUDO_COMMAND = {
|
|
@@ -32951,7 +33128,7 @@ var LAYOUT = [
|
|
|
32951
33128
|
["/usr", 493],
|
|
32952
33129
|
["/usr/local", 493]
|
|
32953
33130
|
];
|
|
32954
|
-
var IN_TREE = /* @__PURE__ */ new Set([SUDO_PATH, VISUDO_PATH, CRONTAB_PATH]);
|
|
33131
|
+
var IN_TREE = /* @__PURE__ */ new Set([SUDO_PATH, VISUDO_PATH, CRONTAB_PATH, SEALED_BIN]);
|
|
32955
33132
|
var LOAD_SAMPLE_MS = 5e3;
|
|
32956
33133
|
var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
|
|
32957
33134
|
var encoder10 = new TextEncoder();
|
|
@@ -33080,6 +33257,7 @@ function expandDefaults(defaults2, env) {
|
|
|
33080
33257
|
function targetOf(command) {
|
|
33081
33258
|
return {
|
|
33082
33259
|
abi: command.abi,
|
|
33260
|
+
command: command.name,
|
|
33083
33261
|
glue: command.glue,
|
|
33084
33262
|
wasm: command.wasm,
|
|
33085
33263
|
argv0: command.argv0,
|
|
@@ -33176,6 +33354,8 @@ var Launcher = class {
|
|
|
33176
33354
|
orphans = /* @__PURE__ */ new Set();
|
|
33177
33355
|
described = /* @__PURE__ */ new Map();
|
|
33178
33356
|
creds = /* @__PURE__ */ new Map();
|
|
33357
|
+
programs = /* @__PURE__ */ new Map();
|
|
33358
|
+
cwdPaths = /* @__PURE__ */ new Map();
|
|
33179
33359
|
tags = /* @__PURE__ */ new Map();
|
|
33180
33360
|
sessions = /* @__PURE__ */ new Map();
|
|
33181
33361
|
tagBases = /* @__PURE__ */ new Map();
|
|
@@ -33503,7 +33683,7 @@ var Launcher = class {
|
|
|
33503
33683
|
this.refusedOf.set(commands, refused4.map(refusing));
|
|
33504
33684
|
return commands;
|
|
33505
33685
|
}).then(
|
|
33506
|
-
(commands) => this.refusals(commands).set(SUDO_COMMAND.name, SUDO_COMMAND).set(VISUDO_COMMAND.name, VISUDO_COMMAND).set(CRONTAB_COMMAND.name, CRONTAB_COMMAND)
|
|
33686
|
+
(commands) => this.refusals(commands).set(SUDO_COMMAND.name, SUDO_COMMAND).set(VISUDO_COMMAND.name, VISUDO_COMMAND).set(CRONTAB_COMMAND.name, CRONTAB_COMMAND).set(SEALED_COMMAND.name, SEALED_COMMAND)
|
|
33507
33687
|
);
|
|
33508
33688
|
this.catalogs.set(scope, found);
|
|
33509
33689
|
}
|
|
@@ -34276,6 +34456,9 @@ var Launcher = class {
|
|
|
34276
34456
|
if (target.abi === "js" && target.wasm === CRONTAB_PATH) {
|
|
34277
34457
|
return { abi: "js", glue: CRONTAB_SOURCE, path: CRONTAB_PATH };
|
|
34278
34458
|
}
|
|
34459
|
+
if (target.abi === "js" && target.wasm === SEALED_BIN) {
|
|
34460
|
+
return { abi: "js", glue: SEALED_SOURCE, path: SEALED_BIN };
|
|
34461
|
+
}
|
|
34279
34462
|
if (target.abi === "js" && target.wasm === REFUSED_PATH) {
|
|
34280
34463
|
return { abi: "js", glue: REFUSED_SOURCE, path: REFUSED_PATH };
|
|
34281
34464
|
}
|
|
@@ -34334,6 +34517,7 @@ var Launcher = class {
|
|
|
34334
34517
|
argv0: target.argv0,
|
|
34335
34518
|
exe: target.copy ?? target.glue,
|
|
34336
34519
|
...exeId,
|
|
34520
|
+
...target.command !== void 0 && target.copy === void 0 ? { command: target.command } : {},
|
|
34337
34521
|
args,
|
|
34338
34522
|
env,
|
|
34339
34523
|
cwdSlot
|
|
@@ -34450,6 +34634,8 @@ var Launcher = class {
|
|
|
34450
34634
|
if (session) this.sessions.set(pid, session);
|
|
34451
34635
|
if (req.tags?.length) this.tagBases.set(pid, req.tagBase ?? req.tags.length);
|
|
34452
34636
|
if (req.links !== void 0) this.links.set(pid, req.links);
|
|
34637
|
+
if (req.command !== void 0) this.programs.set(pid, req.command);
|
|
34638
|
+
this.cwdPaths.set(pid, req.cwd);
|
|
34453
34639
|
}
|
|
34454
34640
|
async admitted(wasm, fds, start2) {
|
|
34455
34641
|
for (; ; ) {
|
|
@@ -34618,6 +34804,7 @@ var Launcher = class {
|
|
|
34618
34804
|
void handle.exited.then(() => {
|
|
34619
34805
|
this.cwds.release(this.cwdSlots.get(pid));
|
|
34620
34806
|
this.cwdSlots.delete(pid);
|
|
34807
|
+
this.cwdPaths.delete(pid);
|
|
34621
34808
|
this.freshModules.forget(pid);
|
|
34622
34809
|
const spent = handle.times?.();
|
|
34623
34810
|
if (spent) this.spent.set(pid, spent);
|
|
@@ -34651,6 +34838,7 @@ var Launcher = class {
|
|
|
34651
34838
|
}
|
|
34652
34839
|
this.jobs.remove(pid);
|
|
34653
34840
|
this.described.delete(pid);
|
|
34841
|
+
this.programs.delete(pid);
|
|
34654
34842
|
const spent = this.spent.get(pid);
|
|
34655
34843
|
if (spent) {
|
|
34656
34844
|
this.reapedTimes.utime += spent.utime;
|
|
@@ -34950,7 +35138,21 @@ var Launcher = class {
|
|
|
34950
35138
|
cwdChdir: (path) => this.chdirHeld(pid, path)
|
|
34951
35139
|
};
|
|
34952
35140
|
}
|
|
35141
|
+
async processFacts(pid) {
|
|
35142
|
+
const described2 = this.described.get(pid);
|
|
35143
|
+
const cwd = this.cwdPaths.get(pid);
|
|
35144
|
+
if (!described2 || described2.exe === void 0 || cwd === void 0) return void 0;
|
|
35145
|
+
const real = (path) => physicalPathAsync(this.base, path).catch(() => path);
|
|
35146
|
+
const command = this.programs.get(pid);
|
|
35147
|
+
return {
|
|
35148
|
+
exe: command !== void 0 ? `/usr/bin/${command}` : await real(described2.exe),
|
|
35149
|
+
argv: [...described2.argv],
|
|
35150
|
+
cwd: await real(cwd),
|
|
35151
|
+
tty: described2.tty
|
|
35152
|
+
};
|
|
35153
|
+
}
|
|
34953
35154
|
async chdirHeld(pid, path) {
|
|
35155
|
+
this.cwdPaths.set(pid, path);
|
|
34954
35156
|
this.cwds.release(this.cwdSlots.get(pid));
|
|
34955
35157
|
const slot2 = await this.cwds.hold(path);
|
|
34956
35158
|
this.cwdSlots.set(pid, slot2);
|
|
@@ -35014,6 +35216,7 @@ var Launcher = class {
|
|
|
35014
35216
|
wireSealed() {
|
|
35015
35217
|
this.sealed.tickets.normalise = (path) => physicalPathAsync(this.base, path);
|
|
35016
35218
|
this.sealed.userOf = async (uid) => (await this.users.lookup(uid))?.name;
|
|
35219
|
+
this.sealed.factsOf = (pid) => this.processFacts(pid);
|
|
35017
35220
|
}
|
|
35018
35221
|
embedderBroker(hook) {
|
|
35019
35222
|
const broker = new EmbedderBroker(
|