@ai-ecoverse/slicc-kernel 1.67.1 → 1.68.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 +10 -0
- package/dist/index.js +49 -2
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +266 -22
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +87 -21
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +222 -15
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +87 -21
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -2019,6 +2019,7 @@ function kernelFdKind(file) {
|
|
|
2019
2019
|
if (file.held) return "held";
|
|
2020
2020
|
if (file.heldMeta && "device" in file.heldMeta) return "device";
|
|
2021
2021
|
if (file.tty) return "tty";
|
|
2022
|
+
if (file.sealed) return "sealed";
|
|
2022
2023
|
return file.seek ? "file" : "stream";
|
|
2023
2024
|
}
|
|
2024
2025
|
var FdTable = class _FdTable {
|
|
@@ -11407,6 +11408,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
11407
11408
|
"fd-open-tty",
|
|
11408
11409
|
"fd-tty-names",
|
|
11409
11410
|
"fd-tty-owner",
|
|
11411
|
+
"fd-open-sealed",
|
|
11410
11412
|
"tty-get",
|
|
11411
11413
|
"tty-set",
|
|
11412
11414
|
"tty-winsz",
|
|
@@ -11462,6 +11464,7 @@ var WasmProcess = class {
|
|
|
11462
11464
|
ignored = 0;
|
|
11463
11465
|
inherited = 0;
|
|
11464
11466
|
interrupt = new AbortController();
|
|
11467
|
+
gone = new AbortController();
|
|
11465
11468
|
dying = false;
|
|
11466
11469
|
umask = DEFAULT_UMASK;
|
|
11467
11470
|
cred;
|
|
@@ -11684,6 +11687,7 @@ var WasmProcess = class {
|
|
|
11684
11687
|
}
|
|
11685
11688
|
async write(fd, body, nonblock = false, cancelled) {
|
|
11686
11689
|
const file = this.fds.get(fd).file;
|
|
11690
|
+
if (file.sealed) return file.sealed.send(body, await this.sealedCaller(), this.gone.signal);
|
|
11687
11691
|
if (!file.write) throw new KernelError("EBADF");
|
|
11688
11692
|
if (!pollFile(file).writable) {
|
|
11689
11693
|
if (nonblock) throw new KernelError("EAGAIN");
|
|
@@ -11765,6 +11769,24 @@ var WasmProcess = class {
|
|
|
11765
11769
|
if (name2 !== void 0) ttyOpenable(this.guarded(), tty);
|
|
11766
11770
|
return this.fds.install(tty.file(), 3);
|
|
11767
11771
|
}
|
|
11772
|
+
openSealed() {
|
|
11773
|
+
const broker = this.options.sealed;
|
|
11774
|
+
if (!broker) throw new KernelError("ENOENT");
|
|
11775
|
+
return this.fds.install(broker.open(), 3);
|
|
11776
|
+
}
|
|
11777
|
+
async sealedCaller() {
|
|
11778
|
+
const shown = await this.options.identity?.();
|
|
11779
|
+
const broker = this.options.sealed;
|
|
11780
|
+
const tag = broker.tagOf(this.pid);
|
|
11781
|
+
return {
|
|
11782
|
+
pid: shown?.pid ?? this.pid,
|
|
11783
|
+
ppid: shown?.ppid ?? 0,
|
|
11784
|
+
uid: this.cred.euid,
|
|
11785
|
+
gid: this.cred.egid,
|
|
11786
|
+
...tag !== void 0 ? { tag } : {},
|
|
11787
|
+
users: broker.users
|
|
11788
|
+
};
|
|
11789
|
+
}
|
|
11768
11790
|
guarded() {
|
|
11769
11791
|
const { guard: guard2 } = this.options;
|
|
11770
11792
|
return guard2 && { fs: guard2.fs, dac: guard2.dac, cred: this.cred, pid: this.pid };
|
|
@@ -11885,6 +11907,8 @@ var WasmProcess = class {
|
|
|
11885
11907
|
return { ok: true, kind: "json", json: this.openTty(req.name) };
|
|
11886
11908
|
case "fd-tty-names":
|
|
11887
11909
|
return { ok: true, kind: "json", json: this.options.jobs?.terminalNames() ?? [] };
|
|
11910
|
+
case "fd-open-sealed":
|
|
11911
|
+
return { ok: true, kind: "json", json: this.openSealed() };
|
|
11888
11912
|
case "fd-tty-owner":
|
|
11889
11913
|
return { ok: true, kind: "json", json: this.terminalByName(req.name).owner ?? null };
|
|
11890
11914
|
case "fd-select": {
|
|
@@ -12320,6 +12344,7 @@ var WasmProcess = class {
|
|
|
12320
12344
|
async exit() {
|
|
12321
12345
|
if (this.exited) return;
|
|
12322
12346
|
this.exited = true;
|
|
12347
|
+
this.gone.abort();
|
|
12323
12348
|
this.die();
|
|
12324
12349
|
this.clearAlarm();
|
|
12325
12350
|
this.interrupt.abort();
|
|
@@ -12507,6 +12532,7 @@ function processOptions(opts, header3, hooks, created3) {
|
|
|
12507
12532
|
return {
|
|
12508
12533
|
...inherited(opts),
|
|
12509
12534
|
...opts.owners ? { owners: true } : {},
|
|
12535
|
+
...opts.sealed ? { sealed: opts.sealed } : {},
|
|
12510
12536
|
...opts.dac ? { guard: { dac: opts.dac, fs: opts.fs, created: created3 } } : {},
|
|
12511
12537
|
...opts.identity ? { identity: opts.identity } : {},
|
|
12512
12538
|
...opts.onSyscall ? { onSyscall: opts.onSyscall } : {},
|
|
@@ -12989,6 +13015,178 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
12989
13015
|
};
|
|
12990
13016
|
}
|
|
12991
13017
|
|
|
13018
|
+
// src/kernel/sealed.ts
|
|
13019
|
+
var SEALED_MAX_BYTES = 64 * 1024;
|
|
13020
|
+
var SEALED_TIMEOUT_MS = 1e4;
|
|
13021
|
+
var SEALED_OPS = /* @__PURE__ */ new Set([
|
|
13022
|
+
"seal",
|
|
13023
|
+
"placeholder",
|
|
13024
|
+
"list",
|
|
13025
|
+
"test",
|
|
13026
|
+
"request",
|
|
13027
|
+
"status",
|
|
13028
|
+
"cancel",
|
|
13029
|
+
"materialize"
|
|
13030
|
+
]);
|
|
13031
|
+
var encoder3 = new TextEncoder();
|
|
13032
|
+
var decoder2 = new TextDecoder("utf-8", { fatal: true });
|
|
13033
|
+
function parseSealed(bytes) {
|
|
13034
|
+
try {
|
|
13035
|
+
if (bytes.length > SEALED_MAX_BYTES) throw new KernelError("EMSGSIZE");
|
|
13036
|
+
let parsed2;
|
|
13037
|
+
try {
|
|
13038
|
+
parsed2 = JSON.parse(decoder2.decode(bytes));
|
|
13039
|
+
} catch {
|
|
13040
|
+
throw new KernelError("EINVAL");
|
|
13041
|
+
}
|
|
13042
|
+
if (typeof parsed2 !== "object" || parsed2 === null || Array.isArray(parsed2))
|
|
13043
|
+
throw new KernelError("EINVAL");
|
|
13044
|
+
const req = parsed2;
|
|
13045
|
+
if (req.v !== 1 || typeof req.op !== "string" || !SEALED_OPS.has(req.op))
|
|
13046
|
+
throw new KernelError("EINVAL");
|
|
13047
|
+
return req;
|
|
13048
|
+
} finally {
|
|
13049
|
+
bytes.fill(0);
|
|
13050
|
+
}
|
|
13051
|
+
}
|
|
13052
|
+
function errorReply(code, message3) {
|
|
13053
|
+
return { v: 1, error: { code, message: message3 } };
|
|
13054
|
+
}
|
|
13055
|
+
function isRecord(value) {
|
|
13056
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13057
|
+
}
|
|
13058
|
+
function serialized(reply) {
|
|
13059
|
+
let plain;
|
|
13060
|
+
try {
|
|
13061
|
+
const text = JSON.stringify(reply);
|
|
13062
|
+
plain = text === void 0 ? void 0 : JSON.parse(text);
|
|
13063
|
+
} catch (err) {
|
|
13064
|
+
return JSON.stringify(errorReply("EIO", lineOf(err)));
|
|
13065
|
+
}
|
|
13066
|
+
if (!isRecord(plain)) return JSON.stringify(errorReply("EIO", "the vault gave no reply"));
|
|
13067
|
+
const { v: _, ...rest2 } = plain;
|
|
13068
|
+
return JSON.stringify({ v: 1, ...rest2 });
|
|
13069
|
+
}
|
|
13070
|
+
function lineOf(err) {
|
|
13071
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
13072
|
+
return (text.split("\n")[0] ?? "").slice(0, 200);
|
|
13073
|
+
}
|
|
13074
|
+
var SealedChannel = class {
|
|
13075
|
+
reply;
|
|
13076
|
+
offset = 0;
|
|
13077
|
+
inflight;
|
|
13078
|
+
broker;
|
|
13079
|
+
constructor(broker) {
|
|
13080
|
+
this.broker = broker;
|
|
13081
|
+
}
|
|
13082
|
+
send(bytes, caller, gone) {
|
|
13083
|
+
const length2 = bytes.length;
|
|
13084
|
+
const fields = parseSealed(bytes);
|
|
13085
|
+
this.reply = void 0;
|
|
13086
|
+
this.offset = 0;
|
|
13087
|
+
this.inflight?.control.abort("replaced");
|
|
13088
|
+
const control = new AbortController();
|
|
13089
|
+
const withdraw = () => control.abort("withdrawn");
|
|
13090
|
+
if (gone.aborted) withdraw();
|
|
13091
|
+
else gone.addEventListener("abort", withdraw, { once: true });
|
|
13092
|
+
const timer = setTimeout(() => control.abort("timeout"), this.broker.timeoutMs);
|
|
13093
|
+
const req = { ...fields, v: 1, op: fields.op, caller };
|
|
13094
|
+
const flight = { control, done: Promise.resolve() };
|
|
13095
|
+
flight.done = this.answer(req, control.signal).then((reply) => {
|
|
13096
|
+
clearTimeout(timer);
|
|
13097
|
+
gone.removeEventListener("abort", withdraw);
|
|
13098
|
+
if (this.inflight !== flight) return;
|
|
13099
|
+
this.inflight = void 0;
|
|
13100
|
+
if (reply) this.reply = encoder3.encode(serialized(reply));
|
|
13101
|
+
});
|
|
13102
|
+
this.inflight = flight;
|
|
13103
|
+
return length2;
|
|
13104
|
+
}
|
|
13105
|
+
async answer(req, signal) {
|
|
13106
|
+
const hook = this.broker.hook;
|
|
13107
|
+
if (!hook) return errorReply("ENOTCONN", "no vault is connected");
|
|
13108
|
+
const stopped = new Promise((resolve) => {
|
|
13109
|
+
signal.addEventListener("abort", () => resolve(void 0), { once: true });
|
|
13110
|
+
});
|
|
13111
|
+
if (signal.aborted) return void 0;
|
|
13112
|
+
const asked = Promise.resolve().then(() => hook(req, { signal })).then(
|
|
13113
|
+
(reply2) => isRecord(reply2) ? reply2 : errorReply("EIO", "the vault gave no reply"),
|
|
13114
|
+
(err) => errorReply("EIO", lineOf(err))
|
|
13115
|
+
);
|
|
13116
|
+
const reply = await Promise.race([asked, stopped]);
|
|
13117
|
+
if (!signal.aborted) return reply;
|
|
13118
|
+
return signal.reason === "timeout" ? errorReply("ETIMEDOUT", "the vault did not answer within 10 s") : void 0;
|
|
13119
|
+
}
|
|
13120
|
+
async read(max, signal) {
|
|
13121
|
+
for (; ; ) {
|
|
13122
|
+
if (this.reply) {
|
|
13123
|
+
const out = this.reply.slice(this.offset, this.offset + max);
|
|
13124
|
+
this.offset += out.length;
|
|
13125
|
+
if (this.offset >= this.reply.length) {
|
|
13126
|
+
this.reply = void 0;
|
|
13127
|
+
this.offset = 0;
|
|
13128
|
+
}
|
|
13129
|
+
return out;
|
|
13130
|
+
}
|
|
13131
|
+
const flight = this.inflight;
|
|
13132
|
+
if (!flight) return new Uint8Array(0);
|
|
13133
|
+
await this.until(flight, signal);
|
|
13134
|
+
}
|
|
13135
|
+
}
|
|
13136
|
+
async until(flight, signal) {
|
|
13137
|
+
if (!signal) return flight.done;
|
|
13138
|
+
if (signal.aborted) throw new KernelError("EINTR");
|
|
13139
|
+
let stop = () => {
|
|
13140
|
+
};
|
|
13141
|
+
const interrupted2 = new Promise((_, reject) => {
|
|
13142
|
+
stop = () => reject(new KernelError("EINTR"));
|
|
13143
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
13144
|
+
});
|
|
13145
|
+
try {
|
|
13146
|
+
await Promise.race([flight.done, interrupted2]);
|
|
13147
|
+
} finally {
|
|
13148
|
+
signal.removeEventListener("abort", stop);
|
|
13149
|
+
}
|
|
13150
|
+
}
|
|
13151
|
+
poll() {
|
|
13152
|
+
return { readable: this.reply !== void 0 || !this.inflight, writable: true, hangup: false };
|
|
13153
|
+
}
|
|
13154
|
+
async changed(signal) {
|
|
13155
|
+
const flight = this.inflight;
|
|
13156
|
+
if (flight) await this.until(flight, signal);
|
|
13157
|
+
}
|
|
13158
|
+
close() {
|
|
13159
|
+
this.inflight?.control.abort("withdrawn");
|
|
13160
|
+
this.inflight = void 0;
|
|
13161
|
+
this.reply = void 0;
|
|
13162
|
+
}
|
|
13163
|
+
};
|
|
13164
|
+
var SealedBroker = class {
|
|
13165
|
+
hook;
|
|
13166
|
+
users;
|
|
13167
|
+
timeoutMs;
|
|
13168
|
+
tagOf;
|
|
13169
|
+
constructor(hook, users, timeoutMs = SEALED_TIMEOUT_MS, tagOf = () => void 0) {
|
|
13170
|
+
this.hook = hook;
|
|
13171
|
+
this.users = users;
|
|
13172
|
+
this.timeoutMs = timeoutMs;
|
|
13173
|
+
this.tagOf = tagOf;
|
|
13174
|
+
}
|
|
13175
|
+
open() {
|
|
13176
|
+
const channel = new SealedChannel(this);
|
|
13177
|
+
return new OpenFile({
|
|
13178
|
+
read: (max, signal) => channel.read(max, signal),
|
|
13179
|
+
write: async () => {
|
|
13180
|
+
throw new KernelError("EINVAL");
|
|
13181
|
+
},
|
|
13182
|
+
poll: () => channel.poll(),
|
|
13183
|
+
changed: (signal) => channel.changed(signal),
|
|
13184
|
+
close: () => channel.close(),
|
|
13185
|
+
sealed: channel
|
|
13186
|
+
});
|
|
13187
|
+
}
|
|
13188
|
+
};
|
|
13189
|
+
|
|
12992
13190
|
// src/kernel/settling.ts
|
|
12993
13191
|
var SETUP_OPS = /* @__PURE__ */ new Set([
|
|
12994
13192
|
"proc-list",
|
|
@@ -13636,13 +13834,13 @@ var HostfsClient = class {
|
|
|
13636
13834
|
const response = await this.send("/api/hostfs/watch", { method: "POST", signal });
|
|
13637
13835
|
onOpen();
|
|
13638
13836
|
const reader = response.body.getReader();
|
|
13639
|
-
const
|
|
13837
|
+
const decoder3 = new TextDecoder();
|
|
13640
13838
|
let buffered = "";
|
|
13641
13839
|
try {
|
|
13642
13840
|
for (; ; ) {
|
|
13643
13841
|
const { done: done4, value } = await reader.read();
|
|
13644
13842
|
if (done4) return;
|
|
13645
|
-
buffered +=
|
|
13843
|
+
buffered += decoder3.decode(value, { stream: true });
|
|
13646
13844
|
let end = buffered.indexOf("\n");
|
|
13647
13845
|
while (end >= 0) {
|
|
13648
13846
|
const line = buffered.slice(0, end).trim();
|
|
@@ -15020,7 +15218,7 @@ var LAYOUT = [
|
|
|
15020
15218
|
];
|
|
15021
15219
|
var LOAD_SAMPLE_MS = 5e3;
|
|
15022
15220
|
var LOAD_WINDOWS_MS = [6e4, 3e5, 9e5];
|
|
15023
|
-
var
|
|
15221
|
+
var encoder4 = new TextEncoder();
|
|
15024
15222
|
var USERS_MODES = ["off", "report", "enforce"];
|
|
15025
15223
|
function usersMode(mode = "off") {
|
|
15026
15224
|
if (USERS_MODES.includes(mode)) return mode;
|
|
@@ -15170,12 +15368,19 @@ var Launcher = class {
|
|
|
15170
15368
|
fstab = Promise.resolve([]);
|
|
15171
15369
|
usersMode;
|
|
15172
15370
|
dac;
|
|
15371
|
+
sealed;
|
|
15173
15372
|
nextPid = 1e3;
|
|
15174
15373
|
boot = Date.now();
|
|
15175
15374
|
terminals = 0;
|
|
15176
15375
|
constructor(options) {
|
|
15177
15376
|
this.usersMode = usersMode(options.users);
|
|
15178
15377
|
this.dac = this.usersMode === "off" ? void 0 : new Dac(this.usersMode, options.onDenial);
|
|
15378
|
+
this.sealed = new SealedBroker(
|
|
15379
|
+
options.sealed,
|
|
15380
|
+
this.usersMode,
|
|
15381
|
+
void 0,
|
|
15382
|
+
(pid) => this.tagOf(pid)
|
|
15383
|
+
);
|
|
15179
15384
|
if (this.owners) options.fs.trackOwners?.();
|
|
15180
15385
|
this.mounts = new MountTable({
|
|
15181
15386
|
open: (type, spec) => this.driver(type, spec),
|
|
@@ -15575,6 +15780,7 @@ var Launcher = class {
|
|
|
15575
15780
|
...req.umask !== void 0 ? { umask: req.umask } : {},
|
|
15576
15781
|
cred: req.cred,
|
|
15577
15782
|
...this.owners ? { owners: true } : {},
|
|
15783
|
+
sealed: this.sealed,
|
|
15578
15784
|
...this.dac ? { dac: this.dac } : {},
|
|
15579
15785
|
program: req.program,
|
|
15580
15786
|
argv0: req.argv0,
|
|
@@ -16213,7 +16419,7 @@ var Launcher = class {
|
|
|
16213
16419
|
},
|
|
16214
16420
|
account
|
|
16215
16421
|
);
|
|
16216
|
-
const report = (message3) => options.onData(
|
|
16422
|
+
const report = (message3) => options.onData(encoder4.encode(`${message3}\r
|
|
16217
16423
|
`));
|
|
16218
16424
|
const handle = await this.launch(planned, {
|
|
16219
16425
|
env,
|
|
@@ -16250,7 +16456,7 @@ var Launcher = class {
|
|
|
16250
16456
|
};
|
|
16251
16457
|
const stdout = collect(out, options.onStdout);
|
|
16252
16458
|
const stderr = collect(err, options.onStderr);
|
|
16253
|
-
const report = (message3) => stderr(
|
|
16459
|
+
const report = (message3) => stderr(encoder4.encode(`${message3}
|
|
16254
16460
|
`));
|
|
16255
16461
|
if (!planned) {
|
|
16256
16462
|
report(`${file}: command not found`);
|
|
@@ -16275,6 +16481,33 @@ var Launcher = class {
|
|
|
16275
16481
|
}
|
|
16276
16482
|
};
|
|
16277
16483
|
|
|
16484
|
+
// src/sealed-relay.ts
|
|
16485
|
+
function sealedAsker(port) {
|
|
16486
|
+
const asks = /* @__PURE__ */ new Map();
|
|
16487
|
+
let next2 = 0;
|
|
16488
|
+
const hook = (req, { signal }) => {
|
|
16489
|
+
const id2 = ++next2;
|
|
16490
|
+
const waiting = Promise.withResolvers();
|
|
16491
|
+
asks.set(id2, waiting);
|
|
16492
|
+
const abort = () => {
|
|
16493
|
+
if (!asks.delete(id2)) return;
|
|
16494
|
+
port.postMessage({ sealedAbort: { id: id2, reason: signal.reason } });
|
|
16495
|
+
waiting.reject(new Error(String(signal.reason)));
|
|
16496
|
+
};
|
|
16497
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
16498
|
+
port.postMessage({ sealedAsk: { id: id2, req } });
|
|
16499
|
+
return waiting.promise.finally(() => signal.removeEventListener("abort", abort));
|
|
16500
|
+
};
|
|
16501
|
+
const answer = ({ id: id2, reply, error }) => {
|
|
16502
|
+
const waiting = asks.get(id2);
|
|
16503
|
+
if (!waiting) return;
|
|
16504
|
+
asks.delete(id2);
|
|
16505
|
+
if (reply) waiting.resolve(reply);
|
|
16506
|
+
else waiting.reject(new Error(error ?? "no reply"));
|
|
16507
|
+
};
|
|
16508
|
+
return { hook, answer };
|
|
16509
|
+
}
|
|
16510
|
+
|
|
16278
16511
|
// src/serve.ts
|
|
16279
16512
|
async function inOpfs(deps, root) {
|
|
16280
16513
|
if (deps.syncAccess !== true) return false;
|
|
@@ -16389,11 +16622,31 @@ function usersOp(l, req) {
|
|
|
16389
16622
|
if (req.op === "groups-remove-member") return l.users.removeMember(req.group, req.user);
|
|
16390
16623
|
return l.users.list();
|
|
16391
16624
|
}
|
|
16392
|
-
function hostOptions(req, port) {
|
|
16625
|
+
function hostOptions(req, port, sealed) {
|
|
16393
16626
|
return {
|
|
16394
16627
|
...req.hostname !== void 0 ? { hostname: req.hostname } : {},
|
|
16395
16628
|
...req.users !== void 0 ? { users: req.users } : {},
|
|
16396
|
-
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {}
|
|
16629
|
+
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {},
|
|
16630
|
+
...req.sealed ? { sealed } : {}
|
|
16631
|
+
};
|
|
16632
|
+
}
|
|
16633
|
+
function policyAsker(port) {
|
|
16634
|
+
const policies = /* @__PURE__ */ new Map();
|
|
16635
|
+
let nextPolicy = 0;
|
|
16636
|
+
const askPolicy = (req) => new Promise((resolve) => {
|
|
16637
|
+
const id2 = ++nextPolicy;
|
|
16638
|
+
policies.set(id2, resolve);
|
|
16639
|
+
port.postMessage({ mountPolicy: { id: id2, req } });
|
|
16640
|
+
});
|
|
16641
|
+
return {
|
|
16642
|
+
mountPolicy: (policy) => policy === void 0 ? {} : { processMounts: policy === "ask" ? askPolicy : policy },
|
|
16643
|
+
allowed(data) {
|
|
16644
|
+
const answer = data.mountAllowed;
|
|
16645
|
+
if (!answer) return false;
|
|
16646
|
+
policies.get(answer.id)?.(answer.allowed);
|
|
16647
|
+
policies.delete(answer.id);
|
|
16648
|
+
return true;
|
|
16649
|
+
}
|
|
16397
16650
|
};
|
|
16398
16651
|
}
|
|
16399
16652
|
function serveKernel(port, deps) {
|
|
@@ -16403,6 +16656,7 @@ function serveKernel(port, deps) {
|
|
|
16403
16656
|
const terminals = /* @__PURE__ */ new Map();
|
|
16404
16657
|
const reply = (id2, body, transfer) => port.postMessage({ id: id2, ...body }, transfer);
|
|
16405
16658
|
const clients = /* @__PURE__ */ new Set();
|
|
16659
|
+
const sealed = sealedAsker(port);
|
|
16406
16660
|
const approvals = sudoApprovals(port);
|
|
16407
16661
|
const locks = deps.locks === null ? void 0 : deps.locks ?? locksOf();
|
|
16408
16662
|
let holding;
|
|
@@ -16467,7 +16721,7 @@ function serveKernel(port, deps) {
|
|
|
16467
16721
|
...deps.createDriverWorker ? { createDriverWorker: deps.createDriverWorker } : {},
|
|
16468
16722
|
...req.modules ? { modules: req.modules } : {},
|
|
16469
16723
|
...req.env ? { env: req.env } : {},
|
|
16470
|
-
...hostOptions(req, port),
|
|
16724
|
+
...hostOptions(req, port, sealed.hook),
|
|
16471
16725
|
...req.approve ? { approve: approvals.ask } : {},
|
|
16472
16726
|
...net,
|
|
16473
16727
|
...media ? { media } : {},
|
|
@@ -16530,23 +16784,13 @@ function serveKernel(port, deps) {
|
|
|
16530
16784
|
if (grant) waiting.resolve(grant);
|
|
16531
16785
|
else waiting.reject(Object.assign(new Error(error ?? "no grant"), { code: "EACCES" }));
|
|
16532
16786
|
}
|
|
16533
|
-
const
|
|
16534
|
-
let nextPolicy = 0;
|
|
16535
|
-
const askPolicy = (req) => new Promise((resolve) => {
|
|
16536
|
-
const id2 = ++nextPolicy;
|
|
16537
|
-
policies.set(id2, resolve);
|
|
16538
|
-
port.postMessage({ mountPolicy: { id: id2, req } });
|
|
16539
|
-
});
|
|
16540
|
-
const mountPolicy = (policy) => policy === void 0 ? {} : { processMounts: policy === "ask" ? askPolicy : policy };
|
|
16787
|
+
const { mountPolicy, allowed } = policyAsker(port);
|
|
16541
16788
|
port.addEventListener("message", (event) => {
|
|
16789
|
+
const sealedReply = event.data.sealedReply;
|
|
16790
|
+
if (sealedReply) return sealed.answer(sealedReply);
|
|
16542
16791
|
const grant = event.data.hostfsGrant;
|
|
16543
16792
|
if (grant) return granted2(grant);
|
|
16544
|
-
|
|
16545
|
-
if (answer) {
|
|
16546
|
-
policies.get(answer.id)?.(answer.allowed);
|
|
16547
|
-
policies.delete(answer.id);
|
|
16548
|
-
return;
|
|
16549
|
-
}
|
|
16793
|
+
if (allowed(event.data)) return;
|
|
16550
16794
|
if (answered(event.data, remote, uplink, approvals)) return;
|
|
16551
16795
|
const req = event.data;
|
|
16552
16796
|
handle(req).then(
|