@ai-ecoverse/slicc-kernel 1.89.0 → 1.90.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 +31 -4
- package/dist/driver-worker.js +89 -1
- package/dist/driver-worker.js.map +3 -3
- package/dist/index.js +135 -5
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +287 -26
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +89 -1
- package/dist/node-driver-worker.js.map +3 -3
- package/dist/node-process-worker.js +76 -2
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +4436 -4102
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +76 -2
- package/dist/process-worker.js.map +3 -3
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -2052,7 +2052,7 @@ function portCdpHook(ask, gone) {
|
|
|
2052
2052
|
}
|
|
2053
2053
|
|
|
2054
2054
|
// src/client/protocol.ts
|
|
2055
|
-
var PROTOCOL = [1,
|
|
2055
|
+
var PROTOCOL = [1, 11];
|
|
2056
2056
|
var FS_METHODS = [
|
|
2057
2057
|
"readFile",
|
|
2058
2058
|
"writeFile",
|
|
@@ -2083,6 +2083,52 @@ function fresh(bytes, start2 = 0, end = bytes.length) {
|
|
|
2083
2083
|
return new Uint8Array(bytes.subarray(start2, end));
|
|
2084
2084
|
}
|
|
2085
2085
|
|
|
2086
|
+
// src/facade/port.ts
|
|
2087
|
+
var FACADE_GONE = "the facade host is gone";
|
|
2088
|
+
function portFacadeHook(ask, gone) {
|
|
2089
|
+
return (stamp, { name: name2 }) => new Promise((resolve2, reject) => {
|
|
2090
|
+
const { port1, port2 } = new MessageChannel();
|
|
2091
|
+
let closed = false;
|
|
2092
|
+
const shut = () => {
|
|
2093
|
+
closed = true;
|
|
2094
|
+
port1.close();
|
|
2095
|
+
};
|
|
2096
|
+
const conn = {
|
|
2097
|
+
send: (bytes) => {
|
|
2098
|
+
if (closed) return;
|
|
2099
|
+
const copy = bytes.slice();
|
|
2100
|
+
port1.postMessage({ b: copy }, [copy.buffer]);
|
|
2101
|
+
},
|
|
2102
|
+
onmessage: null,
|
|
2103
|
+
onclose: null,
|
|
2104
|
+
close: (reason) => {
|
|
2105
|
+
if (closed) return;
|
|
2106
|
+
port1.postMessage({ close: reason ?? true });
|
|
2107
|
+
shut();
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
port1.addEventListener("message", ({ data }) => {
|
|
2111
|
+
if ("b" in data) conn.onmessage?.(data.b);
|
|
2112
|
+
else if ("open" in data) resolve2(conn);
|
|
2113
|
+
else if ("error" in data) {
|
|
2114
|
+
shut();
|
|
2115
|
+
reject(new Error(data.error));
|
|
2116
|
+
} else if (!closed) {
|
|
2117
|
+
shut();
|
|
2118
|
+
conn.onclose?.();
|
|
2119
|
+
}
|
|
2120
|
+
});
|
|
2121
|
+
port1.start();
|
|
2122
|
+
void gone?.then(() => {
|
|
2123
|
+
if (closed) return;
|
|
2124
|
+
shut();
|
|
2125
|
+
reject(new Error(FACADE_GONE));
|
|
2126
|
+
conn.onclose?.(FACADE_GONE);
|
|
2127
|
+
});
|
|
2128
|
+
ask({ name: name2, stamp }, port2);
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2086
2132
|
// src/fs/walk.ts
|
|
2087
2133
|
var MAX_LINKS3 = 40;
|
|
2088
2134
|
function parentOf4(path) {
|
|
@@ -3137,6 +3183,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
3137
3183
|
local;
|
|
3138
3184
|
peer;
|
|
3139
3185
|
peerCred;
|
|
3186
|
+
peerStamp;
|
|
3140
3187
|
listenerCred;
|
|
3141
3188
|
link;
|
|
3142
3189
|
readShut = false;
|
|
@@ -3207,10 +3254,10 @@ var KernelSocket = class _KernelSocket {
|
|
|
3207
3254
|
for (const wait2 of waits) wait2.catch(() => void 0);
|
|
3208
3255
|
return pipeCall(() => Promise.race(waits));
|
|
3209
3256
|
}
|
|
3210
|
-
bind(addr) {
|
|
3257
|
+
bind(addr, kernel = false) {
|
|
3211
3258
|
if (this.state !== "open" || this.local) throw new KernelError("EINVAL");
|
|
3212
3259
|
if (addr.family !== this.domain) throw new KernelError("EAFNOSUPPORT");
|
|
3213
|
-
this.local = this.net.bind(this, addr);
|
|
3260
|
+
this.local = this.net.bind(this, addr, kernel);
|
|
3214
3261
|
this.boundAt = this.local;
|
|
3215
3262
|
}
|
|
3216
3263
|
listen(backlog, cred) {
|
|
@@ -3239,7 +3286,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
3239
3286
|
this.changes.wake();
|
|
3240
3287
|
return true;
|
|
3241
3288
|
}
|
|
3242
|
-
connect(addr, viaUplink = true, cred) {
|
|
3289
|
+
connect(addr, viaUplink = true, cred, stamp) {
|
|
3243
3290
|
if (this.state === "connected") throw new KernelError("EISCONN");
|
|
3244
3291
|
if (this.state === "connecting") throw new KernelError("EALREADY");
|
|
3245
3292
|
if (this.state !== "open") throw new KernelError("EINVAL");
|
|
@@ -3258,6 +3305,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
3258
3305
|
server.local = addr.family === "inet" ? { ...addr, host: canonicalHost(addr.host) } : addr;
|
|
3259
3306
|
server.peer = this.local;
|
|
3260
3307
|
server.peerCred = cred;
|
|
3308
|
+
server.peerStamp = stamp;
|
|
3261
3309
|
this.peer = server.local;
|
|
3262
3310
|
this.peerCred = target.listenerCred;
|
|
3263
3311
|
link(this, server);
|
|
@@ -3398,6 +3446,8 @@ var LoopbackNet = class {
|
|
|
3398
3446
|
bound = /* @__PURE__ */ new Map();
|
|
3399
3447
|
activators = /* @__PURE__ */ new Map();
|
|
3400
3448
|
internal = /* @__PURE__ */ new Set();
|
|
3449
|
+
reserved = /* @__PURE__ */ new Set();
|
|
3450
|
+
facades = /* @__PURE__ */ new Map();
|
|
3401
3451
|
nextEphemeral = EPHEMERAL_FIRST;
|
|
3402
3452
|
route;
|
|
3403
3453
|
useUplink(route) {
|
|
@@ -3412,6 +3462,18 @@ var LoopbackNet = class {
|
|
|
3412
3462
|
if (reserve) this.internal.add(port);
|
|
3413
3463
|
return this.internal.has(port);
|
|
3414
3464
|
}
|
|
3465
|
+
reserve(port) {
|
|
3466
|
+
this.reserved.add(port);
|
|
3467
|
+
}
|
|
3468
|
+
facade(port, name2) {
|
|
3469
|
+
this.reserve(port);
|
|
3470
|
+
this.kernelOnly(port, true);
|
|
3471
|
+
this.facades.set(port, name2);
|
|
3472
|
+
}
|
|
3473
|
+
facadeAt(addr) {
|
|
3474
|
+
if (addr.family !== "inet" || !isLoopback(canonicalHost(addr.host))) return void 0;
|
|
3475
|
+
return this.facades.get(addr.port);
|
|
3476
|
+
}
|
|
3415
3477
|
activate(addr, start2) {
|
|
3416
3478
|
this.activators.set(keyOf(addr), start2);
|
|
3417
3479
|
}
|
|
@@ -3420,7 +3482,7 @@ var LoopbackNet = class {
|
|
|
3420
3482
|
}
|
|
3421
3483
|
listen(addr, backlog = 128) {
|
|
3422
3484
|
const socket = this.socket(addr.family);
|
|
3423
|
-
socket.bind(addr);
|
|
3485
|
+
socket.bind(addr, true);
|
|
3424
3486
|
socket.listen(backlog);
|
|
3425
3487
|
return socket;
|
|
3426
3488
|
}
|
|
@@ -3429,11 +3491,13 @@ var LoopbackNet = class {
|
|
|
3429
3491
|
void socket.connect(addr, false);
|
|
3430
3492
|
return socket;
|
|
3431
3493
|
}
|
|
3432
|
-
bind(socket, addr) {
|
|
3494
|
+
bind(socket, addr, kernel = false) {
|
|
3433
3495
|
if (addr.family === "unix") {
|
|
3434
3496
|
if (addr.path === "") throw new KernelError("EINVAL");
|
|
3435
3497
|
} else if (addr.host !== "0.0.0.0" && !isLoopback(addr.host)) {
|
|
3436
3498
|
throw new KernelError("EADDRNOTAVAIL");
|
|
3499
|
+
} else if (!kernel && this.reserved.has(addr.port)) {
|
|
3500
|
+
throw new KernelError("EADDRINUSE");
|
|
3437
3501
|
}
|
|
3438
3502
|
const named = addr.family === "inet" && addr.port === 0 ? { ...addr, port: this.ephemeral() } : addr;
|
|
3439
3503
|
const key = keyOf(named);
|
|
@@ -3460,7 +3524,7 @@ var LoopbackNet = class {
|
|
|
3460
3524
|
for (let i = 0; i < span; i++) {
|
|
3461
3525
|
const port = this.nextEphemeral;
|
|
3462
3526
|
this.nextEphemeral = port === EPHEMERAL_LAST ? EPHEMERAL_FIRST : port + 1;
|
|
3463
|
-
if (!this.bound.has(`inet:${port}`)) return port;
|
|
3527
|
+
if (!this.bound.has(`inet:${port}`) && !this.reserved.has(port)) return port;
|
|
3464
3528
|
}
|
|
3465
3529
|
throw new KernelError("EADDRINUSE");
|
|
3466
3530
|
}
|
|
@@ -3756,12 +3820,12 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
3756
3820
|
}
|
|
3757
3821
|
sockets.set(call.nid, socket);
|
|
3758
3822
|
peer.postMessage({ net: "ws-opened", nid: call.nid, protocol: socket.protocol });
|
|
3759
|
-
void
|
|
3823
|
+
void relay2(call.nid, socket);
|
|
3760
3824
|
} catch (e) {
|
|
3761
3825
|
fail2(call.nid, e);
|
|
3762
3826
|
}
|
|
3763
3827
|
};
|
|
3764
|
-
const
|
|
3828
|
+
const relay2 = async (nid, socket) => {
|
|
3765
3829
|
let ending;
|
|
3766
3830
|
let late;
|
|
3767
3831
|
const unanswered = new Promise((resolve2) => {
|
|
@@ -4395,6 +4459,45 @@ function cdpRegistry(send, gone) {
|
|
|
4395
4459
|
}
|
|
4396
4460
|
};
|
|
4397
4461
|
}
|
|
4462
|
+
function facadeRegistry(send, gone) {
|
|
4463
|
+
const registered = /* @__PURE__ */ new Map();
|
|
4464
|
+
const drop = (id2) => {
|
|
4465
|
+
registered.get(id2)?.();
|
|
4466
|
+
return registered.delete(id2);
|
|
4467
|
+
};
|
|
4468
|
+
return {
|
|
4469
|
+
serve(l, req) {
|
|
4470
|
+
const hook = portFacadeHook(
|
|
4471
|
+
(request2, facade) => send({ facadeOpen: { ...request2, registration: req.id }, port: facade }, [
|
|
4472
|
+
facade
|
|
4473
|
+
]),
|
|
4474
|
+
gone
|
|
4475
|
+
);
|
|
4476
|
+
registered.set(req.id, l.facades.register(req.name, hook));
|
|
4477
|
+
return req.id;
|
|
4478
|
+
},
|
|
4479
|
+
drop,
|
|
4480
|
+
close: () => {
|
|
4481
|
+
for (const id2 of [...registered.keys()]) drop(id2);
|
|
4482
|
+
}
|
|
4483
|
+
};
|
|
4484
|
+
}
|
|
4485
|
+
function hostRegistries(send, gone) {
|
|
4486
|
+
const cdps = cdpRegistry(send, gone);
|
|
4487
|
+
const facades = facadeRegistry(send, gone);
|
|
4488
|
+
return {
|
|
4489
|
+
answer(l, req) {
|
|
4490
|
+
if (req.op === "serve-cdp") return cdps.serve(l, req);
|
|
4491
|
+
if (req.op === "unserve-cdp") return cdps.drop(req.registration);
|
|
4492
|
+
if (req.op === "serve-facade") return facades.serve(l, req);
|
|
4493
|
+
return facades.drop(req.registration);
|
|
4494
|
+
},
|
|
4495
|
+
close() {
|
|
4496
|
+
cdps.close();
|
|
4497
|
+
facades.close();
|
|
4498
|
+
}
|
|
4499
|
+
};
|
|
4500
|
+
}
|
|
4398
4501
|
function visibleTo(g, notify) {
|
|
4399
4502
|
if (!g?.dac.enforcing) return notify;
|
|
4400
4503
|
let queue = Promise.resolve();
|
|
@@ -4438,7 +4541,7 @@ function serveClient(port, host) {
|
|
|
4438
4541
|
if (state !== "closed") port.postMessage(message3, transfer);
|
|
4439
4542
|
};
|
|
4440
4543
|
const reply = (id2, body, transfer) => send({ id: id2, ...body }, transfer);
|
|
4441
|
-
const
|
|
4544
|
+
const hosts = hostRegistries(send, ended.promise);
|
|
4442
4545
|
function detach(kill = false, bye = "the slicc-kernel detached this client") {
|
|
4443
4546
|
if (state === "closed") return;
|
|
4444
4547
|
send({ bye });
|
|
@@ -4446,7 +4549,7 @@ function serveClient(port, host) {
|
|
|
4446
4549
|
net?.close();
|
|
4447
4550
|
for (const unwatch of watches.values()) unwatch();
|
|
4448
4551
|
watches.clear();
|
|
4449
|
-
|
|
4552
|
+
hosts.close();
|
|
4450
4553
|
for (const session of terminals.values()) session.close();
|
|
4451
4554
|
terminals.clear();
|
|
4452
4555
|
if (kill) killGroups(host, [...groups]);
|
|
@@ -4543,16 +4646,16 @@ function serveClient(port, host) {
|
|
|
4543
4646
|
case "mount":
|
|
4544
4647
|
return { result: await l.mountAs(clientCred(self), req.spec) };
|
|
4545
4648
|
case "umount":
|
|
4546
|
-
await l.umountAs(clientCred(self), req.target);
|
|
4547
|
-
return { result: true };
|
|
4649
|
+
return { result: await l.umountAs(clientCred(self), req.target).then(() => true) };
|
|
4548
4650
|
case "mounts":
|
|
4549
4651
|
return { result: l.mounts.list() };
|
|
4550
4652
|
case "dial":
|
|
4551
4653
|
return dialFor(l, req, watches);
|
|
4552
4654
|
case "serve-cdp":
|
|
4553
|
-
return { result: cdps.serve(l, req) };
|
|
4554
4655
|
case "unserve-cdp":
|
|
4555
|
-
|
|
4656
|
+
case "serve-facade":
|
|
4657
|
+
case "unserve-facade":
|
|
4658
|
+
return { result: hosts.answer(l, req) };
|
|
4556
4659
|
case "detach":
|
|
4557
4660
|
return { result: true };
|
|
4558
4661
|
default:
|
|
@@ -7127,6 +7230,7 @@ var Relay = class {
|
|
|
7127
7230
|
function enableCdp(net, hosts) {
|
|
7128
7231
|
let facade;
|
|
7129
7232
|
net.kernelOnly(CDP_PORT, true);
|
|
7233
|
+
net.reserve(CDP_PORT);
|
|
7130
7234
|
net.activate({ family: "inet", host: "127.0.0.1", port: CDP_PORT }, () => {
|
|
7131
7235
|
const started = new CdpFacade({ net, hosts });
|
|
7132
7236
|
facade = started;
|
|
@@ -7441,9 +7545,9 @@ async function scanFilesystems(fs, modules) {
|
|
|
7441
7545
|
} catch {
|
|
7442
7546
|
continue;
|
|
7443
7547
|
}
|
|
7444
|
-
const
|
|
7445
|
-
if (!
|
|
7446
|
-
for (const [type, entry] of Object.entries(
|
|
7548
|
+
const declared2 = manifest.slicc?.filesystems;
|
|
7549
|
+
if (!declared2 || typeof declared2 !== "object") continue;
|
|
7550
|
+
for (const [type, entry] of Object.entries(declared2)) {
|
|
7447
7551
|
const module = inside(pkg, entry?.module);
|
|
7448
7552
|
if (NAME2.test(type) && module && !found.has(type)) found.set(type, module);
|
|
7449
7553
|
}
|
|
@@ -7461,9 +7565,9 @@ async function scanBinfmts(fs, modules, warn = () => {
|
|
|
7461
7565
|
} catch {
|
|
7462
7566
|
continue;
|
|
7463
7567
|
}
|
|
7464
|
-
const
|
|
7465
|
-
if (!
|
|
7466
|
-
for (const [suffix, command] of Object.entries(
|
|
7568
|
+
const declared2 = manifest.slicc?.binfmt;
|
|
7569
|
+
if (!declared2 || typeof declared2 !== "object") continue;
|
|
7570
|
+
for (const [suffix, command] of Object.entries(declared2)) {
|
|
7467
7571
|
if (!SUFFIX.test(suffix) || typeof command !== "string" || !NAME2.test(command)) continue;
|
|
7468
7572
|
const owner = owners.get(suffix);
|
|
7469
7573
|
if (owner === void 0) {
|
|
@@ -7493,6 +7597,132 @@ function binfmtOf(binfmts, path) {
|
|
|
7493
7597
|
return best === void 0 ? void 0 : binfmts.get(best);
|
|
7494
7598
|
}
|
|
7495
7599
|
|
|
7600
|
+
// src/facade/types.ts
|
|
7601
|
+
var FACADE_NAME = /^[a-z][a-z0-9-]*$/;
|
|
7602
|
+
function facadeEnvName(name2) {
|
|
7603
|
+
return `SLICC_${name2.toUpperCase().replaceAll("-", "_")}_URL`;
|
|
7604
|
+
}
|
|
7605
|
+
function facadeUrl(port) {
|
|
7606
|
+
return `tcp://127.0.0.1:${port}`;
|
|
7607
|
+
}
|
|
7608
|
+
|
|
7609
|
+
// src/facade/hosts.ts
|
|
7610
|
+
var TAKEN_PORTS = /* @__PURE__ */ new Set([CDP_PORT, REALM_PROXY_PORT]);
|
|
7611
|
+
var READ_CHUNK = 64 * 1024;
|
|
7612
|
+
var FACADE_MAX_PENDING = 16 * 1024 * 1024;
|
|
7613
|
+
var FACADE_FLOODED = `slicc-kernel: more than ${FACADE_MAX_PENDING} bytes are waiting for the program to read`;
|
|
7614
|
+
function declared(specs) {
|
|
7615
|
+
const out = /* @__PURE__ */ new Map();
|
|
7616
|
+
const ports = /* @__PURE__ */ new Set();
|
|
7617
|
+
for (const [name2, spec] of Object.entries(specs ?? {})) {
|
|
7618
|
+
if (!FACADE_NAME.test(name2)) throw new TypeError(`facades: not a facade name: ${name2}`);
|
|
7619
|
+
const port = spec?.port;
|
|
7620
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535 || TAKEN_PORTS.has(port)) {
|
|
7621
|
+
throw new TypeError(`facades.${name2}: not a free port: ${String(port)}`);
|
|
7622
|
+
}
|
|
7623
|
+
if (ports.has(port)) throw new TypeError(`facades.${name2}: port ${port} is taken twice`);
|
|
7624
|
+
if (spec.hook !== void 0 && typeof spec.hook !== "function") {
|
|
7625
|
+
throw new TypeError(`facades.${name2}: hook must be a function`);
|
|
7626
|
+
}
|
|
7627
|
+
ports.add(port);
|
|
7628
|
+
out.set(name2, { port, embedder: spec.hook, clients: [] });
|
|
7629
|
+
}
|
|
7630
|
+
return out;
|
|
7631
|
+
}
|
|
7632
|
+
var FacadeHosts = class {
|
|
7633
|
+
facades;
|
|
7634
|
+
constructor(specs) {
|
|
7635
|
+
this.facades = declared(specs);
|
|
7636
|
+
}
|
|
7637
|
+
env() {
|
|
7638
|
+
const env = {};
|
|
7639
|
+
for (const [name2, { port }] of this.facades) env[facadeEnvName(name2)] = facadeUrl(port);
|
|
7640
|
+
return env;
|
|
7641
|
+
}
|
|
7642
|
+
enable(net) {
|
|
7643
|
+
for (const [name2, { port }] of this.facades) {
|
|
7644
|
+
net.facade(port, name2);
|
|
7645
|
+
net.activate({ family: "inet", host: "127.0.0.1", port }, () => {
|
|
7646
|
+
const listener = net.listen({ family: "inet", host: "127.0.0.1", port });
|
|
7647
|
+
void acceptAll(listener, (socket) => this.serve(name2, socket));
|
|
7648
|
+
});
|
|
7649
|
+
}
|
|
7650
|
+
}
|
|
7651
|
+
register(name2, hook) {
|
|
7652
|
+
const entry = this.facades.get(name2);
|
|
7653
|
+
if (!entry || typeof hook !== "function") throw new KernelError("EINVAL");
|
|
7654
|
+
entry.clients.push(hook);
|
|
7655
|
+
return () => {
|
|
7656
|
+
const at = entry.clients.indexOf(hook);
|
|
7657
|
+
if (at >= 0) entry.clients.splice(at, 1);
|
|
7658
|
+
};
|
|
7659
|
+
}
|
|
7660
|
+
async serve(name2, socket) {
|
|
7661
|
+
const entry = this.facades.get(name2);
|
|
7662
|
+
const hook = entry.clients.at(-1) ?? entry.embedder;
|
|
7663
|
+
const stamp = socket.peerStamp;
|
|
7664
|
+
if (!hook || !stamp) return socket.close();
|
|
7665
|
+
let conn;
|
|
7666
|
+
try {
|
|
7667
|
+
conn = await hook(structuredClone(stamp), { name: name2 });
|
|
7668
|
+
} catch {
|
|
7669
|
+
return socket.close();
|
|
7670
|
+
}
|
|
7671
|
+
await relay(socket, conn);
|
|
7672
|
+
}
|
|
7673
|
+
};
|
|
7674
|
+
async function acceptAll(listener, serve) {
|
|
7675
|
+
for (; ; ) {
|
|
7676
|
+
const socket = await listener.accept();
|
|
7677
|
+
void serve(socket);
|
|
7678
|
+
}
|
|
7679
|
+
}
|
|
7680
|
+
async function relay(socket, conn) {
|
|
7681
|
+
let ended = false;
|
|
7682
|
+
let pending = 0;
|
|
7683
|
+
let writes = Promise.resolve();
|
|
7684
|
+
const end = () => {
|
|
7685
|
+
if (ended) return;
|
|
7686
|
+
ended = true;
|
|
7687
|
+
socket.close();
|
|
7688
|
+
};
|
|
7689
|
+
conn.onmessage = (bytes) => {
|
|
7690
|
+
if (ended) return;
|
|
7691
|
+
const chunk2 = bytes.slice();
|
|
7692
|
+
pending += chunk2.length;
|
|
7693
|
+
if (pending > FACADE_MAX_PENDING) {
|
|
7694
|
+
end();
|
|
7695
|
+
conn.close(FACADE_FLOODED);
|
|
7696
|
+
return;
|
|
7697
|
+
}
|
|
7698
|
+
writes = writes.then(async () => {
|
|
7699
|
+
if (ended) return;
|
|
7700
|
+
let at = 0;
|
|
7701
|
+
while (at < chunk2.length) at += await socket.write(chunk2.subarray(at));
|
|
7702
|
+
pending -= chunk2.length;
|
|
7703
|
+
});
|
|
7704
|
+
writes.catch(() => {
|
|
7705
|
+
end();
|
|
7706
|
+
conn.close();
|
|
7707
|
+
});
|
|
7708
|
+
};
|
|
7709
|
+
conn.onclose = () => {
|
|
7710
|
+
writes.then(end, end);
|
|
7711
|
+
};
|
|
7712
|
+
try {
|
|
7713
|
+
for (; ; ) {
|
|
7714
|
+
const bytes = await socket.read(READ_CHUNK);
|
|
7715
|
+
if (bytes.length === 0 || ended) break;
|
|
7716
|
+
conn.send(bytes);
|
|
7717
|
+
}
|
|
7718
|
+
} catch {
|
|
7719
|
+
}
|
|
7720
|
+
if (!ended) {
|
|
7721
|
+
end();
|
|
7722
|
+
conn.close();
|
|
7723
|
+
}
|
|
7724
|
+
}
|
|
7725
|
+
|
|
7496
7726
|
// src/fs/attest.ts
|
|
7497
7727
|
var ATTEST_MAX = 1024 * 1024;
|
|
7498
7728
|
var UNOWNED = 1e3;
|
|
@@ -10849,7 +11079,7 @@ function mountTable(mounts = []) {
|
|
|
10849
11079
|
}
|
|
10850
11080
|
|
|
10851
11081
|
// src/version.ts
|
|
10852
|
-
var KERNEL_VERSION = true ? "1.
|
|
11082
|
+
var KERNEL_VERSION = true ? "1.90.0" : "0.0.0-dev";
|
|
10853
11083
|
var OS_RELEASE = "6.0.0-slicc";
|
|
10854
11084
|
function procVersion() {
|
|
10855
11085
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -12489,7 +12719,9 @@ async function socketSyscall(req, proc) {
|
|
|
12489
12719
|
case "sock-accept":
|
|
12490
12720
|
return ok(await accept(proc, req.fd, req.nonblock));
|
|
12491
12721
|
case "sock-connect": {
|
|
12492
|
-
const
|
|
12722
|
+
const socket = socketAt(fds, req.fd);
|
|
12723
|
+
const stamp = net.facadeAt(req.addr) && await proc.stamp?.();
|
|
12724
|
+
const dialing = socket.connect(req.addr, true, proc.cred?.(), stamp || void 0);
|
|
12493
12725
|
if (req.nonblock) {
|
|
12494
12726
|
dialing?.catch(() => void 0);
|
|
12495
12727
|
throw new KernelError("EINPROGRESS");
|
|
@@ -13668,6 +13900,9 @@ var WasmProcess = class {
|
|
|
13668
13900
|
if (channel) channel.stamp = stamp;
|
|
13669
13901
|
}
|
|
13670
13902
|
}
|
|
13903
|
+
connectorStamp() {
|
|
13904
|
+
return this.sealedCaller();
|
|
13905
|
+
}
|
|
13671
13906
|
async sealedCaller() {
|
|
13672
13907
|
const shown = await this.options.identity?.();
|
|
13673
13908
|
const broker = this.options.sealed;
|
|
@@ -14006,7 +14241,8 @@ var WasmProcess = class {
|
|
|
14006
14241
|
net: this.net,
|
|
14007
14242
|
blocking: () => this.blockingSignal(cancelled),
|
|
14008
14243
|
resolve: (name2, family, blocking) => resolver.resolve(name2, family, blocking),
|
|
14009
|
-
cred: () => ({ pid: this.pid, uid: this.cred.euid, gid: this.cred.egid })
|
|
14244
|
+
cred: () => ({ pid: this.pid, uid: this.cred.euid, gid: this.cred.egid }),
|
|
14245
|
+
stamp: () => this.connectorStamp()
|
|
14010
14246
|
});
|
|
14011
14247
|
}
|
|
14012
14248
|
tty(fd) {
|
|
@@ -18010,6 +18246,7 @@ var Launcher = class {
|
|
|
18010
18246
|
);
|
|
18011
18247
|
net = new LoopbackNet();
|
|
18012
18248
|
cdp;
|
|
18249
|
+
facades;
|
|
18013
18250
|
ca;
|
|
18014
18251
|
transport;
|
|
18015
18252
|
uplink;
|
|
@@ -18084,10 +18321,16 @@ var Launcher = class {
|
|
|
18084
18321
|
this.modulesDir = options.modules ?? "/node_modules";
|
|
18085
18322
|
this.appended = appendedRoots(options.commands);
|
|
18086
18323
|
this.cdp = new CdpHosts(options.cdp);
|
|
18324
|
+
this.facades = new FacadeHosts(options.facades);
|
|
18087
18325
|
const hostname = options.hostname ?? DEFAULT_HOSTNAME;
|
|
18088
18326
|
if (!isHostname(hostname)) throw new Error(`not a host name: ${String(hostname)}`);
|
|
18089
18327
|
this.hostname = hostname;
|
|
18090
|
-
this.env = {
|
|
18328
|
+
this.env = {
|
|
18329
|
+
...networkEnv(hostname),
|
|
18330
|
+
SLICC_CDP_URL: this.cdp.url,
|
|
18331
|
+
...this.facades.env(),
|
|
18332
|
+
...options.env
|
|
18333
|
+
};
|
|
18091
18334
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
18092
18335
|
this.transport = replayingHops(options.transport ?? missingTransport());
|
|
18093
18336
|
this.announcedTraits = JSON.stringify(this.transport.traits);
|
|
@@ -18102,6 +18345,7 @@ var Launcher = class {
|
|
|
18102
18345
|
ca: this.ca
|
|
18103
18346
|
});
|
|
18104
18347
|
enableCdp(this.net, this.cdp);
|
|
18348
|
+
this.facades.enable(this.net);
|
|
18105
18349
|
const fs = withCommandDirs(
|
|
18106
18350
|
this.base,
|
|
18107
18351
|
async () => new Set((await this.commands()).keys()),
|
|
@@ -19035,6 +19279,9 @@ var Launcher = class {
|
|
|
19035
19279
|
}
|
|
19036
19280
|
};
|
|
19037
19281
|
}
|
|
19282
|
+
connectorStamp(pid) {
|
|
19283
|
+
return this.sealed.stamp(this.identityOf(pid), this.credOf(pid), this.tagOf(pid));
|
|
19284
|
+
}
|
|
19038
19285
|
identityOf(pid) {
|
|
19039
19286
|
const parent = this.jobs.shownParent(pid);
|
|
19040
19287
|
const alive = parent !== void 0 && this.running(parent);
|
|
@@ -19706,6 +19953,20 @@ function cdpOption(req, port) {
|
|
|
19706
19953
|
)
|
|
19707
19954
|
};
|
|
19708
19955
|
}
|
|
19956
|
+
function pageHooks(req, port) {
|
|
19957
|
+
return { ...cdpOption(req, port), ...facadesOption(req, port) };
|
|
19958
|
+
}
|
|
19959
|
+
function facadesOption(req, port) {
|
|
19960
|
+
if (!req.facades) return {};
|
|
19961
|
+
const hook = portFacadeHook(
|
|
19962
|
+
(request2, facade) => port.postMessage({ facadeOpen: request2, port: facade }, [facade])
|
|
19963
|
+
);
|
|
19964
|
+
const facades = {};
|
|
19965
|
+
for (const [name2, spec] of Object.entries(req.facades)) {
|
|
19966
|
+
facades[name2] = { port: spec.port, ...spec.hook ? { hook } : {} };
|
|
19967
|
+
}
|
|
19968
|
+
return { facades };
|
|
19969
|
+
}
|
|
19709
19970
|
function remotes(port, req) {
|
|
19710
19971
|
return {
|
|
19711
19972
|
...req.transport ? { transport: new RemoteTransport(port, req.transport) } : {},
|
|
@@ -19919,7 +20180,7 @@ function serveKernel(port, deps) {
|
|
|
19919
20180
|
...media ? { media } : {},
|
|
19920
20181
|
onMountPending: (medium) => port.postMessage({ medium }),
|
|
19921
20182
|
...req.hostfs ? { hostfs: askGrant } : {},
|
|
19922
|
-
...
|
|
20183
|
+
...pageHooks(req, port),
|
|
19923
20184
|
...mountPolicy(req.processMounts),
|
|
19924
20185
|
caStore: caStore(deps.metadata ? caDb(req) : false)
|
|
19925
20186
|
});
|