@ai-ecoverse/slicc-kernel 1.103.4 → 1.106.3
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 +57 -16
- package/dist/driver-worker.js +36 -1
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +89 -5
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +798 -295
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +2 -2
- package/dist/node-driver-worker.js +36 -1
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +489 -234
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +846 -315
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +426 -171
- package/dist/process-worker.js.map +4 -4
- package/dist/types/commands.d.ts +6 -1
- package/dist/types/fs/command-stat.d.ts +3 -0
- package/dist/types/fs/commands.d.ts +7 -1
- package/dist/types/fs/engines.d.ts +5 -0
- package/dist/types/fs/types.d.ts +1 -0
- package/dist/types/kernel/host.d.ts +1 -0
- package/dist/types/kernel/net/http-syscalls.d.ts +10 -0
- package/dist/types/kernel/net/http1.d.ts +1 -0
- package/dist/types/kernel/net/remote-transport.d.ts +18 -0
- package/dist/types/kernel/net/transport.d.ts +2 -0
- package/dist/types/kernel/process.d.ts +8 -0
- package/dist/types/launcher.d.ts +4 -0
- package/dist/types/process/js/js-kernel.d.ts +2 -1
- package/dist/types/process/process-signals.d.ts +3 -0
- package/dist/types/process/wasi/wasi-cred.d.ts +11 -0
- package/dist/types/process/wasi/wasi-files.d.ts +1 -0
- package/dist/types/process/wasi/wasi-host.d.ts +9 -0
- package/dist/types/process/wasi/wasi-sigmask.d.ts +7 -1
- package/dist/types/process/wasi/wasix-epoll.d.ts +3 -0
- package/dist/types/refused-command.d.ts +4 -0
- package/dist/types/transport.d.ts +1 -0
- package/package.json +12 -12
package/dist/node.js
CHANGED
|
@@ -323,11 +323,11 @@ async function realDir(fs, dir, budget = { hops: 0 }) {
|
|
|
323
323
|
at = parentOf(at);
|
|
324
324
|
continue;
|
|
325
325
|
}
|
|
326
|
-
const
|
|
327
|
-
const link2 = await linkOf(fs,
|
|
326
|
+
const next3 = at === "/" ? `/${part}` : `${at}/${part}`;
|
|
327
|
+
const link2 = await linkOf(fs, next3);
|
|
328
328
|
if (link2 === void 0) {
|
|
329
|
-
if (queue.find((p) => p !== ".") === "..") await mustBeDir(fs,
|
|
330
|
-
at =
|
|
329
|
+
if (queue.find((p) => p !== ".") === "..") await mustBeDir(fs, next3);
|
|
330
|
+
at = next3;
|
|
331
331
|
continue;
|
|
332
332
|
}
|
|
333
333
|
if (budget.hops >= MAX_LINKS) throw fsError("ELOOP", dir);
|
|
@@ -430,18 +430,18 @@ async function walk(fs, cred, path, follow2, links) {
|
|
|
430
430
|
at = parentOf(at);
|
|
431
431
|
continue;
|
|
432
432
|
}
|
|
433
|
-
const
|
|
434
|
-
const perm = await perms.at(
|
|
433
|
+
const next3 = joinName(at, part);
|
|
434
|
+
const perm = await perms.at(next3);
|
|
435
435
|
const last = queue.length === 0;
|
|
436
436
|
if (perm?.link !== void 0 && (!last || follow2)) {
|
|
437
|
-
if (!trustedLink(perm, links)) return { path, perm: void 0, denied:
|
|
438
|
-
if (++hops > MAX_LINKS2) return { path:
|
|
437
|
+
if (!trustedLink(perm, links)) return { path, perm: void 0, denied: next3, link: true };
|
|
438
|
+
if (++hops > MAX_LINKS2) return { path: next3, perm: void 0 };
|
|
439
439
|
queue.unshift(...parts(perm.link));
|
|
440
440
|
if (perm.link.startsWith("/")) at = "/";
|
|
441
441
|
continue;
|
|
442
442
|
}
|
|
443
|
-
if (last) return { path:
|
|
444
|
-
at =
|
|
443
|
+
if (last) return { path: next3, perm };
|
|
444
|
+
at = next3;
|
|
445
445
|
}
|
|
446
446
|
return { path: at, perm: await perms.at(at) };
|
|
447
447
|
}
|
|
@@ -546,8 +546,13 @@ function ttyOpenable(g, tty) {
|
|
|
546
546
|
async function need(g, op, path, want, options = {}, shown = path) {
|
|
547
547
|
const walked = await access(g.fs, g.cred, path, want, linked(g, options));
|
|
548
548
|
if (walked.denied !== void 0) deny(g, op, walked.link ? walked.denied : shown);
|
|
549
|
+
else if (want & R_OK && g.fs.commandTarget) await readsAs(g, op, walked.path, shown);
|
|
549
550
|
return walked;
|
|
550
551
|
}
|
|
552
|
+
async function readsAs(g, op, path, shown) {
|
|
553
|
+
const target = await g.fs.commandTarget?.(path);
|
|
554
|
+
if (target !== void 0) await need(g, op, target, R_OK, { directory: false }, shown);
|
|
555
|
+
}
|
|
551
556
|
function entryIn(dir, path) {
|
|
552
557
|
return joinName(dir.path, path.slice(path.lastIndexOf("/") + 1));
|
|
553
558
|
}
|
|
@@ -706,14 +711,14 @@ function changeCred(cur, change) {
|
|
|
706
711
|
throw fsError("EINVAL", "not a change");
|
|
707
712
|
}
|
|
708
713
|
const privileged = cur.euid === 0;
|
|
709
|
-
const
|
|
714
|
+
const next3 = copyCred(cur);
|
|
710
715
|
for (const keys of [UIDS, GIDS]) {
|
|
711
716
|
const own = keys.map((key) => cur[key]);
|
|
712
717
|
for (const key of keys) {
|
|
713
718
|
const value = id(change[key]);
|
|
714
719
|
if (value === void 0) continue;
|
|
715
720
|
if (!privileged && !own.includes(value)) throw fsError("EPERM", `${key} ${value}`);
|
|
716
|
-
|
|
721
|
+
next3[key] = value;
|
|
717
722
|
}
|
|
718
723
|
}
|
|
719
724
|
if (change.groups !== void 0) {
|
|
@@ -723,9 +728,9 @@ function changeCred(cur, change) {
|
|
|
723
728
|
const groups = change.groups.map((g) => id(g) ?? Number.NaN);
|
|
724
729
|
if (groups.some(Number.isNaN)) throw fsError("EINVAL", "not a group list");
|
|
725
730
|
if (!privileged) throw fsError("EPERM", "setgroups");
|
|
726
|
-
|
|
731
|
+
next3.groups = groups;
|
|
727
732
|
}
|
|
728
|
-
return
|
|
733
|
+
return next3;
|
|
729
734
|
}
|
|
730
735
|
function maySignal(sender, target) {
|
|
731
736
|
if (sender.euid === 0) return true;
|
|
@@ -1638,10 +1643,10 @@ var KernelSocket = class _KernelSocket {
|
|
|
1638
1643
|
async accept(signal, nonblock = false) {
|
|
1639
1644
|
for (; ; ) {
|
|
1640
1645
|
if (this.state !== "listening") throw new KernelError("EINVAL");
|
|
1641
|
-
const
|
|
1642
|
-
if (
|
|
1646
|
+
const next3 = this.queue.shift();
|
|
1647
|
+
if (next3) {
|
|
1643
1648
|
this.room.wake();
|
|
1644
|
-
return
|
|
1649
|
+
return next3;
|
|
1645
1650
|
}
|
|
1646
1651
|
if (nonblock) throw new KernelError("EAGAIN");
|
|
1647
1652
|
await this.changes.wait(signal);
|
|
@@ -2181,12 +2186,12 @@ var MessageQueue = class {
|
|
|
2181
2186
|
}
|
|
2182
2187
|
async *[Symbol.asyncIterator]() {
|
|
2183
2188
|
for (; ; ) {
|
|
2184
|
-
const
|
|
2185
|
-
if (
|
|
2186
|
-
const n = payloadSize(
|
|
2189
|
+
const next3 = this.items.shift();
|
|
2190
|
+
if (next3 !== void 0) {
|
|
2191
|
+
const n = payloadSize(next3);
|
|
2187
2192
|
this.size -= n;
|
|
2188
2193
|
this.taken?.(n);
|
|
2189
|
-
yield
|
|
2194
|
+
yield next3;
|
|
2190
2195
|
continue;
|
|
2191
2196
|
}
|
|
2192
2197
|
if (this.ended) return;
|
|
@@ -2313,13 +2318,35 @@ async function* chunks(body, idleMs) {
|
|
|
2313
2318
|
if (!body) return;
|
|
2314
2319
|
const reader = body.getReader();
|
|
2315
2320
|
try {
|
|
2316
|
-
for (let
|
|
2317
|
-
if (
|
|
2321
|
+
for (let next3 = await readWithin(reader, idleMs); !next3.done; next3 = await readWithin(reader, idleMs)) {
|
|
2322
|
+
if (next3.value.byteLength > 0) yield next3.value;
|
|
2318
2323
|
}
|
|
2319
2324
|
} finally {
|
|
2320
2325
|
await reader.cancel().catch(() => void 0);
|
|
2321
2326
|
}
|
|
2322
2327
|
}
|
|
2328
|
+
function streamOf(body) {
|
|
2329
|
+
const it = body[Symbol.asyncIterator]();
|
|
2330
|
+
return new ReadableStream(
|
|
2331
|
+
{
|
|
2332
|
+
async pull(controller) {
|
|
2333
|
+
const next3 = await it.next();
|
|
2334
|
+
if (next3.done) controller.close();
|
|
2335
|
+
else controller.enqueue(next3.value);
|
|
2336
|
+
},
|
|
2337
|
+
async cancel(reason) {
|
|
2338
|
+
await it.return?.(reason);
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2341
|
+
{ highWaterMark: 0 }
|
|
2342
|
+
);
|
|
2343
|
+
}
|
|
2344
|
+
function requestBody(request) {
|
|
2345
|
+
if (request.bodyStream) {
|
|
2346
|
+
return { body: streamOf(request.bodyStream), duplex: "half" };
|
|
2347
|
+
}
|
|
2348
|
+
return request.body ? { body: request.body } : {};
|
|
2349
|
+
}
|
|
2323
2350
|
function fetchTransport(options = {}) {
|
|
2324
2351
|
const send = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
2325
2352
|
const Socket = options.webSocket === true ? globalThis.WebSocket : options.webSocket || void 0;
|
|
@@ -2331,7 +2358,8 @@ function fetchTransport(options = {}) {
|
|
|
2331
2358
|
encodedBodies: false,
|
|
2332
2359
|
maxRequestBody: options.maxRequestBody ?? MAX_REQUEST_BODY,
|
|
2333
2360
|
crossOrigin: "cors",
|
|
2334
|
-
...Socket ? { websocket: true } : {}
|
|
2361
|
+
...Socket ? { websocket: true } : {},
|
|
2362
|
+
...options.streamingBodies ? { streamingBodies: true } : {}
|
|
2335
2363
|
},
|
|
2336
2364
|
...Socket ? { websocket: (request) => openWebSocket(Socket, request, headers) } : {},
|
|
2337
2365
|
async fetch(request) {
|
|
@@ -2340,7 +2368,7 @@ function fetchTransport(options = {}) {
|
|
|
2340
2368
|
response = await send(request.url, {
|
|
2341
2369
|
method: request.method,
|
|
2342
2370
|
headers: joinHeaders(request.headers),
|
|
2343
|
-
...request
|
|
2371
|
+
...requestBody(request),
|
|
2344
2372
|
signal: request.signal,
|
|
2345
2373
|
redirect,
|
|
2346
2374
|
credentials: "omit",
|
|
@@ -2377,6 +2405,29 @@ function fetchTransport(options = {}) {
|
|
|
2377
2405
|
}
|
|
2378
2406
|
};
|
|
2379
2407
|
}
|
|
2408
|
+
function uploadsFor(peer) {
|
|
2409
|
+
const pulls = /* @__PURE__ */ new Map();
|
|
2410
|
+
const of = (nid, signal) => ({
|
|
2411
|
+
async *[Symbol.asyncIterator]() {
|
|
2412
|
+
for (; ; ) {
|
|
2413
|
+
signal.throwIfAborted();
|
|
2414
|
+
const got = await new Promise((resolve2, reject) => {
|
|
2415
|
+
const stop = () => reject(signal.reason);
|
|
2416
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
2417
|
+
pulls.set(nid, (call) => {
|
|
2418
|
+
signal.removeEventListener("abort", stop);
|
|
2419
|
+
resolve2(call);
|
|
2420
|
+
});
|
|
2421
|
+
peer.postMessage({ net: "body-pull", nid });
|
|
2422
|
+
}).finally(() => pulls.delete(nid));
|
|
2423
|
+
if (got.net === "body-end") return;
|
|
2424
|
+
if (got.net === "body-error") throw new Error(got.message);
|
|
2425
|
+
if (got.net === "body-chunk") yield got.bytes;
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
});
|
|
2429
|
+
return { of, answer: (call) => pulls.get(call.nid)?.(call) };
|
|
2430
|
+
}
|
|
2380
2431
|
function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
2381
2432
|
const open = /* @__PURE__ */ new Map();
|
|
2382
2433
|
const fail3 = (nid, e) => {
|
|
@@ -2390,6 +2441,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2390
2441
|
...typeof code === "string" ? { code } : {}
|
|
2391
2442
|
});
|
|
2392
2443
|
};
|
|
2444
|
+
const uploads = uploadsFor(peer);
|
|
2393
2445
|
const start2 = async (call) => {
|
|
2394
2446
|
const abort = new AbortController();
|
|
2395
2447
|
const entry = { abort };
|
|
@@ -2399,7 +2451,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2399
2451
|
url: call.url,
|
|
2400
2452
|
method: call.method,
|
|
2401
2453
|
headers: call.headers,
|
|
2402
|
-
...call.body ? { body: call.body } : {},
|
|
2454
|
+
...call.streamed ? { bodyStream: uploads.of(call.nid, abort.signal) } : call.body ? { body: call.body } : {},
|
|
2403
2455
|
signal: abort.signal
|
|
2404
2456
|
});
|
|
2405
2457
|
if (!open.has(call.nid)) {
|
|
@@ -2471,9 +2523,9 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2471
2523
|
try {
|
|
2472
2524
|
const messages = socket.messages[Symbol.asyncIterator]();
|
|
2473
2525
|
for (; ; ) {
|
|
2474
|
-
const
|
|
2475
|
-
if (
|
|
2476
|
-
const data =
|
|
2526
|
+
const next3 = await Promise.race([messages.next(), unanswered]);
|
|
2527
|
+
if (next3 === "late" || next3.done) break;
|
|
2528
|
+
const data = next3.value;
|
|
2477
2529
|
if (flow.closing) continue;
|
|
2478
2530
|
if (payloadSize(data) > MESSAGE_LIMIT) {
|
|
2479
2531
|
oversize = true;
|
|
@@ -2514,12 +2566,12 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2514
2566
|
const body = open.get(nid)?.body;
|
|
2515
2567
|
if (!body) return;
|
|
2516
2568
|
try {
|
|
2517
|
-
const
|
|
2518
|
-
if (
|
|
2569
|
+
const next3 = await body.next();
|
|
2570
|
+
if (next3.done) {
|
|
2519
2571
|
open.delete(nid);
|
|
2520
2572
|
peer.postMessage({ net: "end", nid });
|
|
2521
2573
|
} else {
|
|
2522
|
-
const bytes = fresh(
|
|
2574
|
+
const bytes = fresh(next3.value);
|
|
2523
2575
|
peer.postMessage({ net: "chunk", nid, bytes }, [bytes.buffer]);
|
|
2524
2576
|
}
|
|
2525
2577
|
} catch (e) {
|
|
@@ -2537,7 +2589,9 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2537
2589
|
return {
|
|
2538
2590
|
answer(call) {
|
|
2539
2591
|
if (call.net === "fetch") void start2(call);
|
|
2540
|
-
else if (call.net === "
|
|
2592
|
+
else if (call.net === "body-chunk" || call.net === "body-end" || call.net === "body-error") {
|
|
2593
|
+
uploads.answer(call);
|
|
2594
|
+
} else if (call.net === "read") void read(call.nid);
|
|
2541
2595
|
else if (call.net === "ws-open") void openSocket(call);
|
|
2542
2596
|
else if (call.net === "ws-send") void sendOn(call);
|
|
2543
2597
|
else if (call.net === "ws-close") {
|
|
@@ -2747,9 +2801,9 @@ var UserDb = class {
|
|
|
2747
2801
|
}
|
|
2748
2802
|
}
|
|
2749
2803
|
serial(work) {
|
|
2750
|
-
const
|
|
2751
|
-
this.writing =
|
|
2752
|
-
return
|
|
2804
|
+
const next3 = this.writing.then(work);
|
|
2805
|
+
this.writing = next3.catch(() => void 0);
|
|
2806
|
+
return next3;
|
|
2753
2807
|
}
|
|
2754
2808
|
async ensure() {
|
|
2755
2809
|
await this.fs.mkdir("/etc", { recursive: true });
|
|
@@ -2948,14 +3002,14 @@ async function realpath(fs, path) {
|
|
|
2948
3002
|
let resolved2 = "";
|
|
2949
3003
|
for (let hops = 0; parts2.length > 0; ) {
|
|
2950
3004
|
const [name2, ...rest2] = parts2;
|
|
2951
|
-
const
|
|
2952
|
-
if (!(await fs.lstat(
|
|
2953
|
-
resolved2 =
|
|
3005
|
+
const next3 = `${resolved2}/${name2}`;
|
|
3006
|
+
if (!(await fs.lstat(next3)).isSymbolicLink) {
|
|
3007
|
+
resolved2 = next3;
|
|
2954
3008
|
parts2 = rest2;
|
|
2955
3009
|
continue;
|
|
2956
3010
|
}
|
|
2957
3011
|
if (++hops > MAX_LINKS3) throw fsError("ELOOP", path);
|
|
2958
|
-
const target = await fs.readlink(
|
|
3012
|
+
const target = await fs.readlink(next3);
|
|
2959
3013
|
const base = target.startsWith("/") ? "/" : resolved2 || "/";
|
|
2960
3014
|
parts2 = [...fs.resolvePath(base, target).split("/").filter(Boolean), ...rest2];
|
|
2961
3015
|
resolved2 = "";
|
|
@@ -3434,9 +3488,9 @@ var PathMap = class {
|
|
|
3434
3488
|
}
|
|
3435
3489
|
link(path) {
|
|
3436
3490
|
for (let child = path, parent = parentOf2(path); parent !== void 0; ) {
|
|
3437
|
-
const
|
|
3438
|
-
if (
|
|
3439
|
-
if (
|
|
3491
|
+
const set3 = this.children.get(parent);
|
|
3492
|
+
if (set3?.has(child)) return;
|
|
3493
|
+
if (set3) set3.add(child);
|
|
3440
3494
|
else this.children.set(parent, /* @__PURE__ */ new Set([child]));
|
|
3441
3495
|
child = parent;
|
|
3442
3496
|
parent = parentOf2(parent);
|
|
@@ -3445,9 +3499,9 @@ var PathMap = class {
|
|
|
3445
3499
|
prune(path) {
|
|
3446
3500
|
for (let child = path, parent = parentOf2(path); parent !== void 0; ) {
|
|
3447
3501
|
if (this.values.has(child) || this.children.has(child)) return;
|
|
3448
|
-
const
|
|
3449
|
-
|
|
3450
|
-
if (
|
|
3502
|
+
const set3 = this.children.get(parent);
|
|
3503
|
+
set3?.delete(child);
|
|
3504
|
+
if (set3 && set3.size > 0) return;
|
|
3451
3505
|
this.children.delete(parent);
|
|
3452
3506
|
child = parent;
|
|
3453
3507
|
parent = parentOf2(parent);
|
|
@@ -3588,14 +3642,14 @@ var Integrity = class {
|
|
|
3588
3642
|
if (!this.root.version) return void 0;
|
|
3589
3643
|
return `${real}\0${await this.root.version(real)}`;
|
|
3590
3644
|
}
|
|
3591
|
-
async read(path, caller,
|
|
3592
|
-
return (await this.readKeyed(path, caller,
|
|
3645
|
+
async read(path, caller, plain2, asked) {
|
|
3646
|
+
return (await this.readKeyed(path, caller, plain2, asked)).bytes;
|
|
3593
3647
|
}
|
|
3594
|
-
async readKeyed(path, caller,
|
|
3648
|
+
async readKeyed(path, caller, plain2, asked) {
|
|
3595
3649
|
const found = await this.real(path, asked);
|
|
3596
|
-
if (found === void 0) return { bytes: await
|
|
3650
|
+
if (found === void 0) return { bytes: await plain2() };
|
|
3597
3651
|
const { real, name: name2 } = found;
|
|
3598
|
-
const read = name2 !== real ? { bytes: await
|
|
3652
|
+
const read = name2 !== real ? { bytes: await plain2(), version: void 0 } : this.root.readVersioned ? await this.root.readVersioned(real) : { bytes: await this.root.readFileBuffer(real), version: void 0 };
|
|
3599
3653
|
const { bytes } = read;
|
|
3600
3654
|
const keyed = read.version === void 0 ? { bytes } : { bytes, key: `${real}\0${read.version}` };
|
|
3601
3655
|
await this.verify(name2, bytes, caller, EXEC_OPS);
|
|
@@ -3604,9 +3658,9 @@ var Integrity = class {
|
|
|
3604
3658
|
get readsChecked() {
|
|
3605
3659
|
return this.sources.length > 0;
|
|
3606
3660
|
}
|
|
3607
|
-
async readSource(path, caller,
|
|
3661
|
+
async readSource(path, caller, plain2) {
|
|
3608
3662
|
const found = await this.source(path);
|
|
3609
|
-
return found === void 0 ?
|
|
3663
|
+
return found === void 0 ? plain2() : this.checked(found, caller, plain2);
|
|
3610
3664
|
}
|
|
3611
3665
|
async openSource(path, caller, real) {
|
|
3612
3666
|
const found = await this.source(path, real);
|
|
@@ -3616,10 +3670,10 @@ var Integrity = class {
|
|
|
3616
3670
|
}
|
|
3617
3671
|
await this.checked(found, caller, () => this.root.readFileBuffer(found.real));
|
|
3618
3672
|
}
|
|
3619
|
-
async checked(found, caller,
|
|
3673
|
+
async checked(found, caller, plain2) {
|
|
3620
3674
|
const { real, name: name2 } = found;
|
|
3621
3675
|
if (name2 !== real || !this.root.readVersioned) {
|
|
3622
|
-
const bytes2 = await
|
|
3676
|
+
const bytes2 = await plain2();
|
|
3623
3677
|
await this.verify(name2, bytes2, caller, READ_OPS);
|
|
3624
3678
|
return bytes2;
|
|
3625
3679
|
}
|
|
@@ -4328,8 +4382,8 @@ var OpfsFs = class {
|
|
|
4328
4382
|
this.refuse(found.path);
|
|
4329
4383
|
const [stored] = found.link ? [found.link] : await this.meta.get([found.path]);
|
|
4330
4384
|
const current = await this.ownerAt(found.path, stored);
|
|
4331
|
-
const
|
|
4332
|
-
const handing = found.handle?.kind === "directory" && !sameOwner(
|
|
4385
|
+
const next3 = { uid: change.uid ?? current.uid, gid: change.gid ?? current.gid };
|
|
4386
|
+
const handing = found.handle?.kind === "directory" && !sameOwner(next3, current);
|
|
4333
4387
|
const heir = change.kind === "adopt" ? void 0 : stored?.heir ?? (handing ? [current.uid, current.gid] : void 0);
|
|
4334
4388
|
const ctimeMs = Date.now();
|
|
4335
4389
|
await this.meta.update(found.path, (entry) => {
|
|
@@ -4337,7 +4391,7 @@ var OpfsFs = class {
|
|
|
4337
4391
|
return {
|
|
4338
4392
|
...rest2,
|
|
4339
4393
|
path: found.path,
|
|
4340
|
-
...
|
|
4394
|
+
...next3,
|
|
4341
4395
|
...heir ? { heir } : {},
|
|
4342
4396
|
...change.mode !== void 0 ? { mode: change.mode & PERM_MASK } : {},
|
|
4343
4397
|
ctimeMs
|
|
@@ -5264,9 +5318,9 @@ var UnlinkedKeeper = class {
|
|
|
5264
5318
|
void locks?.request(lockName(this.instance), () => new Promise(() => void 0));
|
|
5265
5319
|
}
|
|
5266
5320
|
serial(op) {
|
|
5267
|
-
const
|
|
5268
|
-
this.queue =
|
|
5269
|
-
return
|
|
5321
|
+
const next3 = this.queue.then(op);
|
|
5322
|
+
this.queue = next3.catch(() => void 0);
|
|
5323
|
+
return next3;
|
|
5270
5324
|
}
|
|
5271
5325
|
wrap(fs = this.fs) {
|
|
5272
5326
|
const keeper = this;
|
|
@@ -5475,10 +5529,10 @@ var Incoming = class {
|
|
|
5475
5529
|
this.eof = true;
|
|
5476
5530
|
return false;
|
|
5477
5531
|
}
|
|
5478
|
-
const
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
this.buf =
|
|
5532
|
+
const next3 = new Uint8Array(this.buf.length + chunk2.length);
|
|
5533
|
+
next3.set(this.buf);
|
|
5534
|
+
next3.set(chunk2, this.buf.length);
|
|
5535
|
+
this.buf = next3;
|
|
5482
5536
|
return true;
|
|
5483
5537
|
}
|
|
5484
5538
|
take(n) {
|
|
@@ -5618,23 +5672,50 @@ async function readBody(incoming, framing, cap, signal) {
|
|
|
5618
5672
|
const chunks2 = [];
|
|
5619
5673
|
let total = 0;
|
|
5620
5674
|
for (; ; ) {
|
|
5621
|
-
const
|
|
5622
|
-
const size = /^([0-9A-Fa-f]{1,12})[ \t]*(;.*)?$/.exec(sizeLine);
|
|
5623
|
-
if (!size) throw new HttpError(400, "malformed chunk size");
|
|
5624
|
-
const n = Number.parseInt(size[1], 16);
|
|
5675
|
+
const n = await chunkSize(incoming, signal);
|
|
5625
5676
|
if (n === 0) break;
|
|
5626
5677
|
total += n;
|
|
5627
5678
|
if (total > cap) throw new HttpError(413, `request body over ${cap} bytes`);
|
|
5628
5679
|
chunks2.push(await incoming.exactly(n, signal));
|
|
5629
5680
|
if (await incoming.line(2, signal) !== "") throw new HttpError(400, "malformed chunk");
|
|
5630
5681
|
}
|
|
5682
|
+
await skipTrailers(incoming, signal);
|
|
5683
|
+
return concat(chunks2, total);
|
|
5684
|
+
}
|
|
5685
|
+
async function chunkSize(incoming, signal) {
|
|
5686
|
+
const sizeLine = await incoming.line(MAX_CHUNK_LINE, signal);
|
|
5687
|
+
const size = /^([0-9A-Fa-f]{1,12})[ \t]*(;.*)?$/.exec(sizeLine);
|
|
5688
|
+
if (!size) throw new HttpError(400, "malformed chunk size");
|
|
5689
|
+
return Number.parseInt(size[1], 16);
|
|
5690
|
+
}
|
|
5691
|
+
async function skipTrailers(incoming, signal) {
|
|
5631
5692
|
let trailers = 0;
|
|
5632
5693
|
for (let line = await incoming.line(MAX_TRAILERS, signal); line !== ""; ) {
|
|
5633
5694
|
trailers += line.length;
|
|
5634
5695
|
if (trailers > MAX_TRAILERS) throw new HttpError(431, "trailers too large");
|
|
5635
5696
|
line = await incoming.line(MAX_TRAILERS, signal);
|
|
5636
5697
|
}
|
|
5637
|
-
|
|
5698
|
+
}
|
|
5699
|
+
var STREAM_PIECE = 64 * 1024;
|
|
5700
|
+
async function* pieces(incoming, n, signal) {
|
|
5701
|
+
for (let left = n; left > 0; ) {
|
|
5702
|
+
const piece = await incoming.some(Math.min(left, STREAM_PIECE), signal);
|
|
5703
|
+
if (piece.length === 0) throw new HttpError(400, "connection closed inside a body");
|
|
5704
|
+
left -= piece.length;
|
|
5705
|
+
yield piece;
|
|
5706
|
+
}
|
|
5707
|
+
}
|
|
5708
|
+
async function* streamBody(incoming, framing, signal) {
|
|
5709
|
+
if (framing.kind === "none") return;
|
|
5710
|
+
if (framing.kind === "length") {
|
|
5711
|
+
yield* pieces(incoming, framing.length, signal);
|
|
5712
|
+
return;
|
|
5713
|
+
}
|
|
5714
|
+
for (let n = await chunkSize(incoming, signal); n !== 0; n = await chunkSize(incoming, signal)) {
|
|
5715
|
+
yield* pieces(incoming, n, signal);
|
|
5716
|
+
if (await incoming.line(2, signal) !== "") throw new HttpError(400, "malformed chunk");
|
|
5717
|
+
}
|
|
5718
|
+
await skipTrailers(incoming, signal);
|
|
5638
5719
|
}
|
|
5639
5720
|
function concat(chunks2, total = chunks2.reduce((n, c) => n + c.length, 0)) {
|
|
5640
5721
|
const out = new Uint8Array(total);
|
|
@@ -5747,11 +5828,11 @@ function frame(opcode, payload) {
|
|
|
5747
5828
|
return out;
|
|
5748
5829
|
}
|
|
5749
5830
|
function clientFrame(opcode, payload) {
|
|
5750
|
-
const
|
|
5751
|
-
const head =
|
|
5831
|
+
const plain2 = frame(opcode, payload);
|
|
5832
|
+
const head = plain2.length - payload.length;
|
|
5752
5833
|
const mask = crypto.getRandomValues(new Uint8Array(4));
|
|
5753
|
-
const out = new Uint8Array(
|
|
5754
|
-
out.set(
|
|
5834
|
+
const out = new Uint8Array(plain2.length + 4);
|
|
5835
|
+
out.set(plain2.subarray(0, head));
|
|
5755
5836
|
out[1] = out[1] | 128;
|
|
5756
5837
|
out.set(mask, head);
|
|
5757
5838
|
for (let i = 0; i < payload.length; i++) {
|
|
@@ -6203,6 +6284,164 @@ function closeAll(entry) {
|
|
|
6203
6284
|
}
|
|
6204
6285
|
}
|
|
6205
6286
|
|
|
6287
|
+
// src/fs/engines.ts
|
|
6288
|
+
var NUMBER = /^(0|[1-9]\d*)$/;
|
|
6289
|
+
var PART = /^(?:0|[1-9]\d*|[xX*])$/;
|
|
6290
|
+
var IDENTIFIER = /^(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)$/;
|
|
6291
|
+
function identifiers(pre) {
|
|
6292
|
+
if (pre === void 0) return [];
|
|
6293
|
+
const ids = pre.split(".");
|
|
6294
|
+
return ids.every((id2) => IDENTIFIER.test(id2)) ? ids : void 0;
|
|
6295
|
+
}
|
|
6296
|
+
function parseVersion(text) {
|
|
6297
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(text.trim());
|
|
6298
|
+
const pre = identifiers(m?.[4]);
|
|
6299
|
+
if (!m || !pre || ![m[1], m[2], m[3]].every((n) => NUMBER.test(n))) return void 0;
|
|
6300
|
+
return [Number(m[1]), Number(m[2]), Number(m[3]), pre];
|
|
6301
|
+
}
|
|
6302
|
+
function comparePre(a, b) {
|
|
6303
|
+
if (a.length === 0 || b.length === 0) return b.length - a.length;
|
|
6304
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
6305
|
+
const [x, y] = [a[i], b[i]];
|
|
6306
|
+
if (x === void 0 || y === void 0) return x === void 0 ? -1 : 1;
|
|
6307
|
+
if (x === y) continue;
|
|
6308
|
+
const [nx, ny] = [NUMBER.test(x), NUMBER.test(y)];
|
|
6309
|
+
if (nx && ny) return Number(x) - Number(y);
|
|
6310
|
+
if (nx !== ny) return nx ? -1 : 1;
|
|
6311
|
+
return x < y ? -1 : 1;
|
|
6312
|
+
}
|
|
6313
|
+
return 0;
|
|
6314
|
+
}
|
|
6315
|
+
function compare(a, b) {
|
|
6316
|
+
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2] || comparePre(a[3], b[3]);
|
|
6317
|
+
}
|
|
6318
|
+
function partial(text) {
|
|
6319
|
+
const m = /^v?([^.+-]+)(?:\.([^.+-]+))?(?:\.([^.+-]+))?(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(
|
|
6320
|
+
text
|
|
6321
|
+
);
|
|
6322
|
+
if (!m) return void 0;
|
|
6323
|
+
const raw = [m[1], m[2], m[3]];
|
|
6324
|
+
if (!raw.every((p) => p === void 0 || PART.test(p))) return void 0;
|
|
6325
|
+
const parts2 = [];
|
|
6326
|
+
for (const p of raw) {
|
|
6327
|
+
if (p === void 0 || /^[xX*]$/.test(p) || parts2.includes(void 0)) parts2.push(void 0);
|
|
6328
|
+
else parts2.push(Number(p));
|
|
6329
|
+
}
|
|
6330
|
+
const pre = identifiers(m[4]);
|
|
6331
|
+
return pre && { parts: parts2, pre };
|
|
6332
|
+
}
|
|
6333
|
+
function floor(p) {
|
|
6334
|
+
const [a = 0, b = 0, c = 0] = p.parts;
|
|
6335
|
+
return [a, b, c, p.parts.includes(void 0) ? [] : p.pre];
|
|
6336
|
+
}
|
|
6337
|
+
function next(p) {
|
|
6338
|
+
const [a, b] = p.parts;
|
|
6339
|
+
if (a === void 0) return void 0;
|
|
6340
|
+
if (b === void 0) return [a + 1, 0, 0, ["0"]];
|
|
6341
|
+
return [a, b + 1, 0, ["0"]];
|
|
6342
|
+
}
|
|
6343
|
+
var ANY = [[">=", [0, 0, 0, []]]];
|
|
6344
|
+
var NOTHING = [["<", [0, 0, 0, ["0"]]]];
|
|
6345
|
+
function plain(op, p) {
|
|
6346
|
+
const exact = !p.parts.includes(void 0);
|
|
6347
|
+
const low = floor(p);
|
|
6348
|
+
const high = next(p);
|
|
6349
|
+
if (op === ">=") return [[">=", low]];
|
|
6350
|
+
if (op === "<") return [["<", exact ? low : [low[0], low[1], low[2], ["0"]]]];
|
|
6351
|
+
if (exact) return [[op === "" ? "=" : op, low]];
|
|
6352
|
+
if (op === ">") return high ? [[">=", high]] : NOTHING;
|
|
6353
|
+
if (op === "<=") return high ? [["<", high]] : ANY;
|
|
6354
|
+
return high ? [
|
|
6355
|
+
[">=", low],
|
|
6356
|
+
["<", high]
|
|
6357
|
+
] : ANY;
|
|
6358
|
+
}
|
|
6359
|
+
function caret(p) {
|
|
6360
|
+
const [a = 0, b, c] = p.parts;
|
|
6361
|
+
const low = floor(p);
|
|
6362
|
+
if (b === void 0)
|
|
6363
|
+
return [
|
|
6364
|
+
[">=", low],
|
|
6365
|
+
["<", [a + 1, 0, 0, ["0"]]]
|
|
6366
|
+
];
|
|
6367
|
+
if (a > 0)
|
|
6368
|
+
return [
|
|
6369
|
+
[">=", low],
|
|
6370
|
+
["<", [a + 1, 0, 0, ["0"]]]
|
|
6371
|
+
];
|
|
6372
|
+
if (c === void 0 || b > 0)
|
|
6373
|
+
return [
|
|
6374
|
+
[">=", low],
|
|
6375
|
+
["<", [0, b + 1, 0, ["0"]]]
|
|
6376
|
+
];
|
|
6377
|
+
return [
|
|
6378
|
+
[">=", low],
|
|
6379
|
+
["<", [0, b, c + 1, ["0"]]]
|
|
6380
|
+
];
|
|
6381
|
+
}
|
|
6382
|
+
function tilde(p) {
|
|
6383
|
+
const [a = 0, b] = p.parts;
|
|
6384
|
+
const low = floor(p);
|
|
6385
|
+
return [
|
|
6386
|
+
[">=", low],
|
|
6387
|
+
["<", b === void 0 ? [a + 1, 0, 0, ["0"]] : [a, b + 1, 0, ["0"]]]
|
|
6388
|
+
];
|
|
6389
|
+
}
|
|
6390
|
+
function hyphen(from, to) {
|
|
6391
|
+
const high = to.parts.includes(void 0) ? next(to) : void 0;
|
|
6392
|
+
const upper = to.parts.includes(void 0) ? high ? [["<", high]] : [] : [["<=", floor(to)]];
|
|
6393
|
+
return [[">=", floor(from)], ...upper];
|
|
6394
|
+
}
|
|
6395
|
+
function comparator(token) {
|
|
6396
|
+
const m = /^(<=|>=|<|>|=|\^|~>?)?\s*(.*)$/.exec(token);
|
|
6397
|
+
const op = m?.[1] ?? "";
|
|
6398
|
+
const p = partial(m?.[2] ?? "");
|
|
6399
|
+
if (!p) return void 0;
|
|
6400
|
+
const wild = p.parts[0] === void 0;
|
|
6401
|
+
if (op === "^") return wild ? ANY : caret(p);
|
|
6402
|
+
if (op.startsWith("~")) return wild ? ANY : tilde(p);
|
|
6403
|
+
return plain(op, p);
|
|
6404
|
+
}
|
|
6405
|
+
function set(text) {
|
|
6406
|
+
const trimmed = text.trim().replace(/(<=|>=|<|>|=|\^|~>?)\s+/g, "$1");
|
|
6407
|
+
if (trimmed === "") return ANY;
|
|
6408
|
+
const range = /^(\S+)\s+-\s+(\S+)$/.exec(trimmed);
|
|
6409
|
+
if (range) {
|
|
6410
|
+
const [from, to] = [partial(range[1]), partial(range[2])];
|
|
6411
|
+
return from && to ? hyphen(from, to) : void 0;
|
|
6412
|
+
}
|
|
6413
|
+
const out = [];
|
|
6414
|
+
for (const token of trimmed.split(/\s+/)) {
|
|
6415
|
+
const found = comparator(token);
|
|
6416
|
+
if (!found) return void 0;
|
|
6417
|
+
out.push(...found);
|
|
6418
|
+
}
|
|
6419
|
+
return out;
|
|
6420
|
+
}
|
|
6421
|
+
function holds(v, [op, w]) {
|
|
6422
|
+
const c = compare(v, w);
|
|
6423
|
+
if (op === "<") return c < 0;
|
|
6424
|
+
if (op === "<=") return c <= 0;
|
|
6425
|
+
if (op === ">") return c > 0;
|
|
6426
|
+
if (op === ">=") return c >= 0;
|
|
6427
|
+
return c === 0;
|
|
6428
|
+
}
|
|
6429
|
+
function satisfies(version, range) {
|
|
6430
|
+
const v = parseVersion(version);
|
|
6431
|
+
if (!v) return void 0;
|
|
6432
|
+
const sets = range.split("||").map(set);
|
|
6433
|
+
if (sets.some((s) => s === void 0)) return void 0;
|
|
6434
|
+
return sets.some((s) => s.every((c) => holds(v, c)));
|
|
6435
|
+
}
|
|
6436
|
+
|
|
6437
|
+
// src/version.ts
|
|
6438
|
+
var KERNEL_VERSION = true ? "1.106.3" : "0.0.0-dev";
|
|
6439
|
+
var OS_RELEASE = "6.0.0-slicc";
|
|
6440
|
+
function procVersion() {
|
|
6441
|
+
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
6442
|
+
`;
|
|
6443
|
+
}
|
|
6444
|
+
|
|
6206
6445
|
// src/commands.ts
|
|
6207
6446
|
var NAME2 = /^[A-Za-z0-9._+-]+$/;
|
|
6208
6447
|
var COMMAND_NAME = /^[^/\s\p{Cc}]+$/u;
|
|
@@ -6414,13 +6653,25 @@ async function binCommandsOf(physical, pkg, manifest, taken) {
|
|
|
6414
6653
|
}
|
|
6415
6654
|
return out;
|
|
6416
6655
|
}
|
|
6656
|
+
function engineRefusal(manifest, kernel) {
|
|
6657
|
+
const engines = manifest.engines;
|
|
6658
|
+
const range = engines && typeof engines === "object" ? engines["slicc-kernel"] : void 0;
|
|
6659
|
+
const running = parseVersion(kernel);
|
|
6660
|
+
if (typeof range !== "string" || !running || running.slice(0, 3).every((n) => n === 0)) {
|
|
6661
|
+
return void 0;
|
|
6662
|
+
}
|
|
6663
|
+
const fits = satisfies(kernel, range);
|
|
6664
|
+
if (fits) return void 0;
|
|
6665
|
+
const who = `${String(manifest.name ?? "?")}@${String(manifest.version ?? "?")}`;
|
|
6666
|
+
return fits === false ? `${who} needs slicc-kernel ${range}; this kernel is ${kernel}` : `${who} has an engines.slicc-kernel range this kernel can't read: ${JSON.stringify(range)}`;
|
|
6667
|
+
}
|
|
6417
6668
|
var PACKAGE_NAME = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
6418
6669
|
function replacesOf(manifest) {
|
|
6419
6670
|
const replaces = manifest.slicc?.replaces;
|
|
6420
6671
|
if (!Array.isArray(replaces)) return [];
|
|
6421
6672
|
return replaces.every((name2) => typeof name2 === "string" && PACKAGE_NAME.test(name2)) ? replaces : [];
|
|
6422
6673
|
}
|
|
6423
|
-
async function tierPackages(fs, physical, roots, bins) {
|
|
6674
|
+
async function tierPackages(fs, physical, roots, bins, kernel) {
|
|
6424
6675
|
const out = [];
|
|
6425
6676
|
for (const root of roots) {
|
|
6426
6677
|
for (const pkg of await packages(fs, root)) {
|
|
@@ -6433,11 +6684,13 @@ async function tierPackages(fs, physical, roots, bins) {
|
|
|
6433
6684
|
const own = commandsOf(pkg, manifest);
|
|
6434
6685
|
const named = new Set(own.map((command) => command.name));
|
|
6435
6686
|
const extra = bins ? await binCommandsOf(physical, pkg, manifest, named) : [];
|
|
6687
|
+
const refused2 = engineRefusal(manifest, kernel);
|
|
6688
|
+
const commands = [...own, ...extra];
|
|
6436
6689
|
out.push({
|
|
6437
6690
|
name: pkg.slice(root.length + 1),
|
|
6438
6691
|
pkg,
|
|
6439
6692
|
replaces: replacesOf(manifest),
|
|
6440
|
-
commands:
|
|
6693
|
+
commands: refused2 ? commands.map((command) => ({ ...command, refused: refused2 })) : commands
|
|
6441
6694
|
});
|
|
6442
6695
|
}
|
|
6443
6696
|
}
|
|
@@ -6463,14 +6716,14 @@ function winners(tier) {
|
|
|
6463
6716
|
}
|
|
6464
6717
|
return out;
|
|
6465
6718
|
}
|
|
6466
|
-
async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY) {
|
|
6719
|
+
async function scanCommands(fs, modules, binsFrom = Number.POSITIVE_INFINITY, kernel = KERNEL_VERSION) {
|
|
6467
6720
|
const found = /* @__PURE__ */ new Map();
|
|
6468
6721
|
const physical = physicalResolver(fs);
|
|
6469
6722
|
const tiers = (typeof modules === "string" ? [modules] : modules).map(
|
|
6470
6723
|
(tier) => typeof tier === "string" ? [tier] : tier
|
|
6471
6724
|
);
|
|
6472
6725
|
for (const [index, roots] of tiers.entries()) {
|
|
6473
|
-
const tier = await tierPackages(fs, physical, roots, index >= binsFrom);
|
|
6726
|
+
const tier = await tierPackages(fs, physical, roots, index >= binsFrom, kernel);
|
|
6474
6727
|
for (const [name2, { pkg, command }] of winners(tier)) {
|
|
6475
6728
|
if (!found.has(name2)) found.set(name2, await withPackagePaths(fs, pkg, command));
|
|
6476
6729
|
}
|
|
@@ -6719,6 +6972,11 @@ async function watchHangup(conn, abort, until) {
|
|
|
6719
6972
|
}
|
|
6720
6973
|
}
|
|
6721
6974
|
}
|
|
6975
|
+
var BODILESS_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
6976
|
+
async function* drain(body, done4) {
|
|
6977
|
+
yield* body;
|
|
6978
|
+
done4();
|
|
6979
|
+
}
|
|
6722
6980
|
function untilAborted(response, signal) {
|
|
6723
6981
|
return new Promise((resolve2, reject) => {
|
|
6724
6982
|
const onAbort = () => {
|
|
@@ -6861,7 +7119,8 @@ var RealmProxy = class {
|
|
|
6861
7119
|
const url = ctx.origin ? tunnelRequestUrl(req, ctx.origin) : requestUrl(req);
|
|
6862
7120
|
const keep2 = keepsAlive(req);
|
|
6863
7121
|
const framing = requestFraming(req.headers);
|
|
6864
|
-
const
|
|
7122
|
+
const streaming = this.options.transport.traits.streamingBodies === true && framing.kind !== "none" && !BODILESS_METHODS.has(req.method);
|
|
7123
|
+
const reserve = streaming ? 0 : framing.kind === "length" ? framing.length : framing.kind === "chunked" ? this.cap() : 0;
|
|
6865
7124
|
if (reserve > this.cap()) throw new HttpError(413, `request body over ${this.cap()} bytes`);
|
|
6866
7125
|
await this.expectContinue(conn, req, framing.kind !== "none");
|
|
6867
7126
|
await this.bodies.acquire(reserve, this.stop.signal);
|
|
@@ -6869,9 +7128,12 @@ var RealmProxy = class {
|
|
|
6869
7128
|
const abort = new AbortController();
|
|
6870
7129
|
const stopExchange = () => abort.abort();
|
|
6871
7130
|
this.stop.signal.addEventListener("abort", stopExchange, { once: true });
|
|
7131
|
+
let drained = !streaming;
|
|
6872
7132
|
try {
|
|
6873
7133
|
try {
|
|
6874
|
-
const body =
|
|
7134
|
+
const body = streaming ? drain(streamBody(incoming, framing, abort.signal), () => {
|
|
7135
|
+
drained = true;
|
|
7136
|
+
}) : await readBody(incoming, framing, this.cap());
|
|
6875
7137
|
const waiting = new AbortController();
|
|
6876
7138
|
void watchHangup(ctx.socket, abort, waiting.signal);
|
|
6877
7139
|
try {
|
|
@@ -6882,7 +7144,8 @@ var RealmProxy = class {
|
|
|
6882
7144
|
} finally {
|
|
6883
7145
|
this.bodies.release(reserve);
|
|
6884
7146
|
}
|
|
6885
|
-
|
|
7147
|
+
const kept = await this.relay(conn, req.method, req.minor, response, keep2 && drained);
|
|
7148
|
+
return kept && drained;
|
|
6886
7149
|
} finally {
|
|
6887
7150
|
this.stop.signal.removeEventListener("abort", stopExchange);
|
|
6888
7151
|
abort.abort();
|
|
@@ -6902,13 +7165,14 @@ var RealmProxy = class {
|
|
|
6902
7165
|
}
|
|
6903
7166
|
}
|
|
6904
7167
|
async upstream(req, url, body, signal, owner) {
|
|
7168
|
+
const sent = BODILESS_METHODS.has(req.method) ? void 0 : body;
|
|
6905
7169
|
try {
|
|
6906
7170
|
const fetching = this.options.transport.fetch(
|
|
6907
7171
|
{
|
|
6908
7172
|
url: toHostLoopback(url),
|
|
6909
7173
|
method: req.method.toUpperCase(),
|
|
6910
7174
|
headers: forwardRequestHeaders(req.headers),
|
|
6911
|
-
body:
|
|
7175
|
+
...sent instanceof Uint8Array ? { body: sent } : sent ? { bodyStream: sent } : {},
|
|
6912
7176
|
signal
|
|
6913
7177
|
},
|
|
6914
7178
|
owner
|
|
@@ -7404,6 +7668,7 @@ var S_IFDIR2 = 16384;
|
|
|
7404
7668
|
var S_IFREG2 = 32768;
|
|
7405
7669
|
var COMMAND = /^\/(?:usr\/)?bin\/([^/]+)$/;
|
|
7406
7670
|
var MAX_LINKS6 = 40;
|
|
7671
|
+
var BIN_ENTRY = /\/bin\/[^/]+$/;
|
|
7407
7672
|
function missing3(err) {
|
|
7408
7673
|
return err?.code === "ENOENT";
|
|
7409
7674
|
}
|
|
@@ -7431,7 +7696,20 @@ async function followLinks(fs, path) {
|
|
|
7431
7696
|
}
|
|
7432
7697
|
return current;
|
|
7433
7698
|
}
|
|
7434
|
-
|
|
7699
|
+
var NOBODY = { ruid: -1, euid: -1, suid: -1, rgid: -1, egid: -1, sgid: -1, groups: [] };
|
|
7700
|
+
var EMPTY = new Uint8Array(0);
|
|
7701
|
+
function quiet2(promise) {
|
|
7702
|
+
return promise.catch(() => void 0);
|
|
7703
|
+
}
|
|
7704
|
+
async function readsAs2(fs, cred, target) {
|
|
7705
|
+
const walked = await quiet2(access(fs, cred, target, R_OK, { directory: false }));
|
|
7706
|
+
return walked !== void 0 && walked.denied === void 0 && !walked.missing;
|
|
7707
|
+
}
|
|
7708
|
+
async function shownTarget(fs, target) {
|
|
7709
|
+
const st = await quiet2(fs.stat(target));
|
|
7710
|
+
return st?.isFile && await readsAs2(fs, NOBODY, target) ? st : void 0;
|
|
7711
|
+
}
|
|
7712
|
+
function withCommandDirs(fs, names, userDir = async () => void 0, owners = false, targetOf2 = async () => void 0) {
|
|
7435
7713
|
async function nearest(path) {
|
|
7436
7714
|
const st = await fs.stat(path).catch(() => void 0);
|
|
7437
7715
|
if (st || path === "/") return st ?? {};
|
|
@@ -7463,9 +7741,54 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7463
7741
|
const own = await userDir(dir);
|
|
7464
7742
|
return own?.has(path.slice(slash + 1)) ? owned4(synthetic(false, path), dir) : void 0;
|
|
7465
7743
|
}
|
|
7744
|
+
let generation;
|
|
7745
|
+
const targets = /* @__PURE__ */ new Map();
|
|
7746
|
+
async function targetStat(target) {
|
|
7747
|
+
const now = await names();
|
|
7748
|
+
if (now !== generation) {
|
|
7749
|
+
generation = now;
|
|
7750
|
+
targets.clear();
|
|
7751
|
+
}
|
|
7752
|
+
let found = targets.get(target);
|
|
7753
|
+
if (!found) {
|
|
7754
|
+
found = shownTarget(fs, target);
|
|
7755
|
+
targets.set(target, found);
|
|
7756
|
+
}
|
|
7757
|
+
return found;
|
|
7758
|
+
}
|
|
7759
|
+
async function shown(path) {
|
|
7760
|
+
const st = await virtual(path);
|
|
7761
|
+
if (!st?.isFile) return st;
|
|
7762
|
+
const target = await targetOf2(path);
|
|
7763
|
+
const real = target === void 0 ? void 0 : await targetStat(target.path);
|
|
7764
|
+
return real ? { ...st, size: real.size, mtime: real.mtime, ctime: real.mtime, atime: real.mtime } : st;
|
|
7765
|
+
}
|
|
7466
7766
|
async function linked2(path) {
|
|
7467
|
-
return await
|
|
7767
|
+
return await shown(path) ?? shown(await followLinks(fs, path));
|
|
7768
|
+
}
|
|
7769
|
+
async function entryTarget(path) {
|
|
7770
|
+
if (!BIN_ENTRY.test(path) || !(await virtual(path))?.isFile) return void 0;
|
|
7771
|
+
if (!await fs.lstat(path).then(() => false, missing3)) return void 0;
|
|
7772
|
+
const target = await targetOf2(path);
|
|
7773
|
+
return target?.path === path ? void 0 : target;
|
|
7774
|
+
}
|
|
7775
|
+
async function redirected2(path) {
|
|
7776
|
+
const target = await entryTarget(path) ?? await entryTarget(await followLinks(fs, path));
|
|
7777
|
+
if (owners && target?.owner && !await readsAs2(fs, target.owner, target.path)) {
|
|
7778
|
+
throw fsError("EACCES", path);
|
|
7779
|
+
}
|
|
7780
|
+
return target?.path;
|
|
7781
|
+
}
|
|
7782
|
+
const absent2 = (err) => {
|
|
7783
|
+
if (missing3(err)) return EMPTY;
|
|
7784
|
+
throw err;
|
|
7785
|
+
};
|
|
7786
|
+
async function content(path, err) {
|
|
7787
|
+
if (!missing3(err) || !(await linked2(path))?.isFile) throw err;
|
|
7788
|
+
const target = await redirected2(path);
|
|
7789
|
+
return target === void 0 ? EMPTY : fs.readFileBuffer(target).catch(absent2);
|
|
7468
7790
|
}
|
|
7791
|
+
const ranged2 = rangedOps(fs);
|
|
7469
7792
|
async function stat(path, real) {
|
|
7470
7793
|
try {
|
|
7471
7794
|
return await real(path);
|
|
@@ -7477,16 +7800,13 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7477
7800
|
}
|
|
7478
7801
|
return {
|
|
7479
7802
|
resolvePath: (base, path) => fs.resolvePath(base, path),
|
|
7480
|
-
readFile: (path) => fs.readFile(path)
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
}
|
|
7488
|
-
},
|
|
7489
|
-
writeFile: (path, content, owner) => fs.writeFile(path, content, owner),
|
|
7803
|
+
readFile: (path) => fs.readFile(path).catch(async (err) => {
|
|
7804
|
+
if (!BIN_ENTRY.test(await followLinks(fs, path))) throw err;
|
|
7805
|
+
return new TextDecoder().decode(await content(path, err));
|
|
7806
|
+
}),
|
|
7807
|
+
readFileBuffer: (path) => fs.readFileBuffer(path).catch((err) => content(path, err)),
|
|
7808
|
+
commandTarget: async (path) => (await entryTarget(path))?.path,
|
|
7809
|
+
writeFile: (path, content2, owner) => fs.writeFile(path, content2, owner),
|
|
7490
7810
|
link: (from, to, follow2) => fs.link(from, to, follow2),
|
|
7491
7811
|
links: (path) => mayLink(fs, path),
|
|
7492
7812
|
async exists(path) {
|
|
@@ -7517,7 +7837,7 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7517
7837
|
added.map(
|
|
7518
7838
|
async (name2) => [
|
|
7519
7839
|
name2,
|
|
7520
|
-
await
|
|
7840
|
+
await shown(`${base}/${name2}`)
|
|
7521
7841
|
]
|
|
7522
7842
|
)
|
|
7523
7843
|
);
|
|
@@ -7535,7 +7855,14 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7535
7855
|
chmod: (path, mode) => fs.chmod(path, mode),
|
|
7536
7856
|
utimes: (path, atime, mtime) => fs.utimes(path, atime, mtime),
|
|
7537
7857
|
lutimes: (path, atime, mtime) => lutimesOf(fs, path, atime, mtime),
|
|
7538
|
-
...
|
|
7858
|
+
...ranged2 ? {
|
|
7859
|
+
...ranged2,
|
|
7860
|
+
pread: (path, offset, length2, version) => ranged2.pread(path, offset, length2, version).catch(async (err) => {
|
|
7861
|
+
const target = missing3(err) ? await redirected2(path) : void 0;
|
|
7862
|
+
if (target === void 0) throw err;
|
|
7863
|
+
return ranged2.pread(target, offset, length2).catch(absent2);
|
|
7864
|
+
})
|
|
7865
|
+
} : {}
|
|
7539
7866
|
};
|
|
7540
7867
|
}
|
|
7541
7868
|
|
|
@@ -7680,7 +8007,7 @@ var MAX_HOPS2 = 40;
|
|
|
7680
8007
|
function start(path) {
|
|
7681
8008
|
return { done: [], todo: path.split("/").filter((p) => p !== ""), hops: 0 };
|
|
7682
8009
|
}
|
|
7683
|
-
function
|
|
8010
|
+
function next2(walk2) {
|
|
7684
8011
|
while (walk2.todo.length > 0) {
|
|
7685
8012
|
const part = walk2.todo.shift();
|
|
7686
8013
|
if (part === ".") continue;
|
|
@@ -7694,7 +8021,7 @@ function next(walk2) {
|
|
|
7694
8021
|
}
|
|
7695
8022
|
function lexical(path) {
|
|
7696
8023
|
const walk2 = start(path);
|
|
7697
|
-
for (let part =
|
|
8024
|
+
for (let part = next2(walk2); part !== void 0; part = next2(walk2)) walk2.done.push(part);
|
|
7698
8025
|
return `/${walk2.done.join("/")}`;
|
|
7699
8026
|
}
|
|
7700
8027
|
function rest(walk2, part) {
|
|
@@ -7708,7 +8035,7 @@ function follow(walk2, target) {
|
|
|
7708
8035
|
}
|
|
7709
8036
|
async function physicalPathAsync(fs, path) {
|
|
7710
8037
|
const walk2 = start(path);
|
|
7711
|
-
for (let part =
|
|
8038
|
+
for (let part = next2(walk2); part !== void 0; part = next2(walk2)) {
|
|
7712
8039
|
const at = `/${[...walk2.done, part].join("/")}`;
|
|
7713
8040
|
let target;
|
|
7714
8041
|
try {
|
|
@@ -8006,7 +8333,8 @@ var ChildTable = class {
|
|
|
8006
8333
|
const child = this.children.get(pid);
|
|
8007
8334
|
if (!child) return;
|
|
8008
8335
|
this.watchers.set(pid, listener);
|
|
8009
|
-
if (child.stoppedBy !== void 0
|
|
8336
|
+
if (child.stoppedBy !== void 0 && child.code === void 0)
|
|
8337
|
+
listener("stopped", child.stoppedBy);
|
|
8010
8338
|
}
|
|
8011
8339
|
openSlot(slot2, n, captured) {
|
|
8012
8340
|
if ("fd" in slot2) return this.parentFds.get(slot2.fd).retain();
|
|
@@ -8475,14 +8803,14 @@ var HeldSet = class extends Set {
|
|
|
8475
8803
|
super();
|
|
8476
8804
|
this.idle = idle;
|
|
8477
8805
|
}
|
|
8478
|
-
add(
|
|
8479
|
-
|
|
8480
|
-
return super.add(
|
|
8806
|
+
add(holds2) {
|
|
8807
|
+
holds2.onIdle = this.idle;
|
|
8808
|
+
return super.add(holds2);
|
|
8481
8809
|
}
|
|
8482
|
-
delete(
|
|
8483
|
-
const removed = super.delete(
|
|
8484
|
-
for (const path of /* @__PURE__ */ new Set([...
|
|
8485
|
-
|
|
8810
|
+
delete(holds2) {
|
|
8811
|
+
const removed = super.delete(holds2);
|
|
8812
|
+
for (const path of /* @__PURE__ */ new Set([...holds2.keys(), ...holds2.opens.keys()])) this.idle(path);
|
|
8813
|
+
holds2.releaseAll();
|
|
8486
8814
|
return removed;
|
|
8487
8815
|
}
|
|
8488
8816
|
};
|
|
@@ -9669,9 +9997,9 @@ var MountFs = class _MountFs {
|
|
|
9669
9997
|
this.writable(mount, real);
|
|
9670
9998
|
const { uid, gid, mode } = change;
|
|
9671
9999
|
const fresh2 = change.kind === "new" && { uid, gid, mode };
|
|
9672
|
-
const
|
|
10000
|
+
const set3 = fresh2 ? await this.driverOwner(found, real, fresh2, false) : change;
|
|
9673
10001
|
this.table.forget(mount, real);
|
|
9674
|
-
const attrs = Object.entries({ uid:
|
|
10002
|
+
const attrs = Object.entries({ uid: set3.uid, gid: set3.gid, mode: set3.mode });
|
|
9675
10003
|
await mount.conn.call({
|
|
9676
10004
|
op: "setattr",
|
|
9677
10005
|
path: rel2,
|
|
@@ -9698,11 +10026,11 @@ var MountFs = class _MountFs {
|
|
|
9698
10026
|
const real = await this.follow(path);
|
|
9699
10027
|
const found = this.at(real);
|
|
9700
10028
|
if (!found) {
|
|
9701
|
-
const
|
|
10029
|
+
const set3 = () => this.base.utimes(real, atime, mtime);
|
|
9702
10030
|
return this.based(
|
|
9703
10031
|
[real],
|
|
9704
10032
|
redirects,
|
|
9705
|
-
|
|
10033
|
+
set3,
|
|
9706
10034
|
([to], n) => this.utimes(to, atime, mtime, n)
|
|
9707
10035
|
);
|
|
9708
10036
|
}
|
|
@@ -9711,11 +10039,11 @@ var MountFs = class _MountFs {
|
|
|
9711
10039
|
async lutimes(path, atime, mtime, redirects = 0) {
|
|
9712
10040
|
const found = this.at(path);
|
|
9713
10041
|
if (!found) {
|
|
9714
|
-
const
|
|
10042
|
+
const set3 = () => lutimesOf(this.base, path, atime, mtime);
|
|
9715
10043
|
return this.based(
|
|
9716
10044
|
[path],
|
|
9717
10045
|
redirects,
|
|
9718
|
-
|
|
10046
|
+
set3,
|
|
9719
10047
|
([to], n) => this.lutimes(to, atime, mtime, n)
|
|
9720
10048
|
);
|
|
9721
10049
|
}
|
|
@@ -9737,6 +10065,20 @@ var MountFs = class _MountFs {
|
|
|
9737
10065
|
}
|
|
9738
10066
|
};
|
|
9739
10067
|
|
|
10068
|
+
// src/fs/command-stat.ts
|
|
10069
|
+
async function callerStat(g, path, st) {
|
|
10070
|
+
if (!g?.fs.commandTarget || !st.isFile || st.size > 0) return st;
|
|
10071
|
+
const target = await g.fs.commandTarget(path);
|
|
10072
|
+
if (target === void 0) return st;
|
|
10073
|
+
const options = { directory: false, ...g.links === void 0 ? {} : { links: g.links } };
|
|
10074
|
+
const walked = await access(g.fs, g.cred, target, R_OK, options).catch(() => void 0);
|
|
10075
|
+
if (!walked || walked.denied !== void 0 || walked.missing) return st;
|
|
10076
|
+
const real = await g.fs.stat(target).catch(() => void 0);
|
|
10077
|
+
if (!real?.isFile) return st;
|
|
10078
|
+
const { size, mtime } = real;
|
|
10079
|
+
return { ...st, size, mtime, atime: mtime, ctime: mtime };
|
|
10080
|
+
}
|
|
10081
|
+
|
|
9740
10082
|
// src/realm/sync-fs-token-registry.ts
|
|
9741
10083
|
var registry = /* @__PURE__ */ new Map();
|
|
9742
10084
|
function mintSyncFsToken(entry) {
|
|
@@ -9823,8 +10165,10 @@ function statJson(s) {
|
|
|
9823
10165
|
...s.gid !== void 0 ? { gid: s.gid } : {}
|
|
9824
10166
|
};
|
|
9825
10167
|
}
|
|
9826
|
-
async function readdirStat(fs, dir) {
|
|
9827
|
-
|
|
10168
|
+
async function readdirStat(fs, dir, g) {
|
|
10169
|
+
const listed = await fs.readdirStat(dir);
|
|
10170
|
+
const shown = async (name2, stat) => stat && statJson(await callerStat(g, joinName(dir, name2), stat));
|
|
10171
|
+
return Promise.all(listed.map(async ([name2, stat]) => [name2, await shown(name2, stat)]));
|
|
9828
10172
|
}
|
|
9829
10173
|
async function usageAt(entry, path) {
|
|
9830
10174
|
if (!entry.statfs) return void 0;
|
|
@@ -9893,18 +10237,22 @@ async function chown(entry, path, req) {
|
|
|
9893
10237
|
}
|
|
9894
10238
|
async function runMkdir(entry, path, req) {
|
|
9895
10239
|
const { fs } = entry;
|
|
9896
|
-
const
|
|
10240
|
+
const plain2 = plainDirMode(entry, req.mode);
|
|
9897
10241
|
const parentsMode = !req.exclusive ? plainParentsMode(entry) : void 0;
|
|
9898
10242
|
const fixParents = parentsMode !== void 0 ? await missingParents(fs, path, parentsMode) : void 0;
|
|
9899
|
-
const fresh2 =
|
|
10243
|
+
const fresh2 = plain2 !== void 0 && !await fs.exists(path);
|
|
9900
10244
|
await (req.exclusive ? mkdirExclusive(entry, path, req.mode) : fs.mkdir(path, mkdirOptions(entry, req.mode)));
|
|
9901
10245
|
await fixParents?.();
|
|
9902
|
-
if (fresh2) await fs.chmod(path,
|
|
10246
|
+
if (fresh2) await fs.chmod(path, plain2);
|
|
9903
10247
|
return done;
|
|
9904
10248
|
}
|
|
10249
|
+
async function shownAs(entry, path, st) {
|
|
10250
|
+
const real = st.isFile && st.size === 0 ? entry.fs.realpath?.(path, true) : void 0;
|
|
10251
|
+
return callerStat(guardOf(entry), await real?.catch(() => path) ?? path, st);
|
|
10252
|
+
}
|
|
9905
10253
|
function readSource(entry, path) {
|
|
9906
|
-
const
|
|
9907
|
-
return entry.source ? entry.source.read(path,
|
|
10254
|
+
const plain2 = () => entry.fs.readFileBuffer(path);
|
|
10255
|
+
return entry.source ? entry.source.read(path, plain2) : plain2();
|
|
9908
10256
|
}
|
|
9909
10257
|
async function run(entry, path, req) {
|
|
9910
10258
|
const { fs, cwd } = entry;
|
|
@@ -9917,13 +10265,13 @@ async function run(entry, path, req) {
|
|
|
9917
10265
|
case "exists":
|
|
9918
10266
|
return json2(await fs.exists(path));
|
|
9919
10267
|
case "stat":
|
|
9920
|
-
return json2(statJson(await fs.stat(path)));
|
|
10268
|
+
return json2(statJson(await shownAs(entry, path, await fs.stat(path))));
|
|
9921
10269
|
case "lstat":
|
|
9922
|
-
return json2(statJson(await fs.lstat(path)));
|
|
10270
|
+
return json2(statJson(await shownAs(entry, path, await fs.lstat(path))));
|
|
9923
10271
|
case "readdir":
|
|
9924
10272
|
return json2(await fs.readdir(path));
|
|
9925
10273
|
case "readdir-stat":
|
|
9926
|
-
return json2(await readdirStat(fs, path));
|
|
10274
|
+
return json2(await readdirStat(fs, path, guardOf(entry)));
|
|
9927
10275
|
case "mkdir":
|
|
9928
10276
|
return runMkdir(entry, path, req);
|
|
9929
10277
|
case "rm":
|
|
@@ -10859,18 +11207,18 @@ var KernelDgram = class {
|
|
|
10859
11207
|
const pending = this.takeError();
|
|
10860
11208
|
if (pending) throw new KernelError(pending);
|
|
10861
11209
|
if (this.closed) throw new KernelError("EBADF");
|
|
10862
|
-
const
|
|
10863
|
-
if (
|
|
11210
|
+
const next3 = this.queue[0];
|
|
11211
|
+
if (next3) {
|
|
10864
11212
|
if (!peek) {
|
|
10865
11213
|
this.queue.shift();
|
|
10866
|
-
this.queued -=
|
|
11214
|
+
this.queued -= next3.bytes.length;
|
|
10867
11215
|
this.changes.wake();
|
|
10868
11216
|
}
|
|
10869
11217
|
const size = Math.max(0, max);
|
|
10870
11218
|
return {
|
|
10871
|
-
bytes:
|
|
10872
|
-
from:
|
|
10873
|
-
truncated:
|
|
11219
|
+
bytes: next3.bytes.slice(0, size),
|
|
11220
|
+
from: next3.from,
|
|
11221
|
+
truncated: next3.bytes.length > size
|
|
10874
11222
|
};
|
|
10875
11223
|
}
|
|
10876
11224
|
await this.changes.wait(signal);
|
|
@@ -11189,14 +11537,6 @@ var PATH_OPS = new Set(SYNC_FS_OPS);
|
|
|
11189
11537
|
// src/realm/live-vfs-fs.ts
|
|
11190
11538
|
var EARLY_WHOLE_FILE = 64 * 1024;
|
|
11191
11539
|
|
|
11192
|
-
// src/version.ts
|
|
11193
|
-
var KERNEL_VERSION = true ? "1.103.4" : "0.0.0-dev";
|
|
11194
|
-
var OS_RELEASE = "6.0.0-slicc";
|
|
11195
|
-
function procVersion() {
|
|
11196
|
-
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
11197
|
-
`;
|
|
11198
|
-
}
|
|
11199
|
-
|
|
11200
11540
|
// src/process/process-fds.ts
|
|
11201
11541
|
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
11202
11542
|
var pinnedRoot;
|
|
@@ -11588,7 +11928,7 @@ function* procWalk(path, follow2) {
|
|
|
11588
11928
|
const whole = normalize(`/${[...done4, part, ...todo].join("/")}`);
|
|
11589
11929
|
if (inProc(at) && inProc(whole)) return broken ?? whole;
|
|
11590
11930
|
if (!follow2 && todo.length === 0) return void 0;
|
|
11591
|
-
const target = yield { at, check: todo.find((
|
|
11931
|
+
const target = yield { at, check: todo.find((next3) => next3 !== ".") === ".." };
|
|
11592
11932
|
if (typeof target === "string") {
|
|
11593
11933
|
if (++hops > MAX_HOPS3) return void 0;
|
|
11594
11934
|
[done4, todo] = throughLink(target, done4, todo);
|
|
@@ -11724,18 +12064,18 @@ function timerAfter(ms, fire) {
|
|
|
11724
12064
|
return timerAt(performance.now() + ms, fire);
|
|
11725
12065
|
}
|
|
11726
12066
|
function repeating(first, every, fire) {
|
|
11727
|
-
let
|
|
12067
|
+
let next3 = performance.now() + first;
|
|
11728
12068
|
let cancel = () => {
|
|
11729
12069
|
};
|
|
11730
12070
|
const tick = () => {
|
|
11731
12071
|
fire();
|
|
11732
12072
|
if (every <= 0) return;
|
|
11733
|
-
|
|
12073
|
+
next3 += every;
|
|
11734
12074
|
const now = performance.now();
|
|
11735
|
-
if (
|
|
11736
|
-
cancel = timerAt(
|
|
12075
|
+
if (next3 <= now) next3 += (Math.floor((now - next3) / every) + 1) * every;
|
|
12076
|
+
cancel = timerAt(next3, tick);
|
|
11737
12077
|
};
|
|
11738
|
-
cancel = timerAt(
|
|
12078
|
+
cancel = timerAt(next3, tick);
|
|
11739
12079
|
return () => cancel();
|
|
11740
12080
|
}
|
|
11741
12081
|
|
|
@@ -12026,11 +12366,11 @@ var LockTable = class {
|
|
|
12026
12366
|
}
|
|
12027
12367
|
changed(key, signal) {
|
|
12028
12368
|
return new Promise((resolve2, reject) => {
|
|
12029
|
-
const
|
|
12030
|
-
this.wakers.set(key,
|
|
12369
|
+
const set3 = this.wakers.get(key) ?? /* @__PURE__ */ new Set();
|
|
12370
|
+
this.wakers.set(key, set3);
|
|
12031
12371
|
const done4 = () => {
|
|
12032
|
-
|
|
12033
|
-
if (
|
|
12372
|
+
set3.delete(wake);
|
|
12373
|
+
if (set3.size === 0 && this.wakers.get(key) === set3) this.wakers.delete(key);
|
|
12034
12374
|
signal.removeEventListener("abort", abort);
|
|
12035
12375
|
};
|
|
12036
12376
|
const wake = () => {
|
|
@@ -12041,7 +12381,7 @@ var LockTable = class {
|
|
|
12041
12381
|
done4();
|
|
12042
12382
|
reject(new KernelError("EINTR"));
|
|
12043
12383
|
};
|
|
12044
|
-
|
|
12384
|
+
set3.add(wake);
|
|
12045
12385
|
signal.addEventListener("abort", abort, { once: true });
|
|
12046
12386
|
});
|
|
12047
12387
|
}
|
|
@@ -12342,9 +12682,10 @@ var MAX_UNREAD = 16 * 1024 * 1024;
|
|
|
12342
12682
|
function errno(code, message3) {
|
|
12343
12683
|
return Object.assign(new Error(`${code}: ${message3}`), { code });
|
|
12344
12684
|
}
|
|
12345
|
-
function requestHead(method, url, headers, extra) {
|
|
12685
|
+
function requestHead(method, url, headers, extra, first = []) {
|
|
12346
12686
|
if (!TOKEN3.test(method)) throw errno("EINVAL", `method ${method}`);
|
|
12347
|
-
const lines2 = [`${method} ${url.pathname}${url.search} HTTP/1.1`, `
|
|
12687
|
+
const lines2 = [`${method} ${url.pathname}${url.search} HTTP/1.1`, `host: ${url.host}`];
|
|
12688
|
+
for (const [name2, value] of first) lines2.push(`${name2}: ${value}`);
|
|
12348
12689
|
for (const [name2, value] of headers) {
|
|
12349
12690
|
if (OWN_HEADERS.has(name2.toLowerCase())) continue;
|
|
12350
12691
|
if (!TOKEN3.test(name2) || !SAFE_VALUE.test(value)) throw errno("EINVAL", `header ${name2}`);
|
|
@@ -12459,8 +12800,8 @@ var KernelLoopback = class {
|
|
|
12459
12800
|
async fetch(req, port) {
|
|
12460
12801
|
const url = new URL(req.url);
|
|
12461
12802
|
const body = req.body ?? (/^(POST|PUT|PATCH)$/i.test(req.method) ? new Uint8Array(0) : void 0);
|
|
12462
|
-
const length2 = body ? [["
|
|
12463
|
-
const head = requestHead(req.method, url, req.headers,
|
|
12803
|
+
const length2 = body ? [["content-length", String(body.length)]] : [];
|
|
12804
|
+
const head = requestHead(req.method, url, req.headers, length2, [["connection", "close"]]);
|
|
12464
12805
|
const socket = await this.connect(url, port, req.signal);
|
|
12465
12806
|
try {
|
|
12466
12807
|
await writeAll2(socket, body ? concat([head, body]) : head, req.signal);
|
|
@@ -12553,7 +12894,7 @@ var LoopbackWebSocket = class {
|
|
|
12553
12894
|
const queue = [];
|
|
12554
12895
|
let wake;
|
|
12555
12896
|
let ended = false;
|
|
12556
|
-
void this.pump(
|
|
12897
|
+
void this.pump(incoming, (message3) => {
|
|
12557
12898
|
queue.push(message3);
|
|
12558
12899
|
this.unread += message3.length;
|
|
12559
12900
|
wake?.();
|
|
@@ -12570,10 +12911,10 @@ var LoopbackWebSocket = class {
|
|
|
12570
12911
|
this.messages = {
|
|
12571
12912
|
[Symbol.asyncIterator]: async function* () {
|
|
12572
12913
|
for (; ; ) {
|
|
12573
|
-
const
|
|
12574
|
-
if (
|
|
12575
|
-
taken(
|
|
12576
|
-
yield
|
|
12914
|
+
const next3 = queue.shift();
|
|
12915
|
+
if (next3 !== void 0) {
|
|
12916
|
+
taken(next3);
|
|
12917
|
+
yield next3;
|
|
12577
12918
|
continue;
|
|
12578
12919
|
}
|
|
12579
12920
|
if (ended) return;
|
|
@@ -12608,7 +12949,8 @@ var LoopbackWebSocket = class {
|
|
|
12608
12949
|
this.pending -= bytes.length;
|
|
12609
12950
|
})();
|
|
12610
12951
|
}
|
|
12611
|
-
async pump(
|
|
12952
|
+
async pump(incoming, deliver) {
|
|
12953
|
+
const reader = new WsReader(incoming, void 0, true, true);
|
|
12612
12954
|
let close = { code: 1006, reason: "", wasClean: false };
|
|
12613
12955
|
try {
|
|
12614
12956
|
for (; ; ) {
|
|
@@ -12630,11 +12972,18 @@ var LoopbackWebSocket = class {
|
|
|
12630
12972
|
} finally {
|
|
12631
12973
|
const late = setTimeout(() => this.stop.abort(), CLOSE_WAIT_MS3);
|
|
12632
12974
|
await this.writes;
|
|
12975
|
+
if (close.wasClean) await this.serverEnd(incoming);
|
|
12633
12976
|
clearTimeout(late);
|
|
12634
12977
|
this.socket.close();
|
|
12635
12978
|
this.settle(close);
|
|
12636
12979
|
}
|
|
12637
12980
|
}
|
|
12981
|
+
async serverEnd(incoming) {
|
|
12982
|
+
try {
|
|
12983
|
+
while ((await incoming.some(64 * 1024, this.stop.signal)).length > 0) ;
|
|
12984
|
+
} catch {
|
|
12985
|
+
}
|
|
12986
|
+
}
|
|
12638
12987
|
sendClose(code, reason) {
|
|
12639
12988
|
if (this.sentClose) return;
|
|
12640
12989
|
this.sentClose = true;
|
|
@@ -12678,7 +13027,7 @@ function tlv(tag, ...contents2) {
|
|
|
12678
13027
|
return concat4([Uint8Array.of(tag), length(body.length), body]);
|
|
12679
13028
|
}
|
|
12680
13029
|
var seq = (...parts2) => tlv(48, ...parts2);
|
|
12681
|
-
var
|
|
13030
|
+
var set2 = (...parts2) => tlv(49, ...parts2);
|
|
12682
13031
|
var octets = (bytes) => tlv(4, bytes);
|
|
12683
13032
|
var bits = (bytes, unused = 0) => tlv(3, Uint8Array.of(unused), bytes);
|
|
12684
13033
|
var TRUE = tlv(1, Uint8Array.of(255));
|
|
@@ -12711,8 +13060,8 @@ function time(date) {
|
|
|
12711
13060
|
var ECDSA_SHA256 = seq(oid("1.2.840.10045.4.3.2"));
|
|
12712
13061
|
function name(dn) {
|
|
12713
13062
|
const rdns = [];
|
|
12714
|
-
if (dn.organization) rdns.push(
|
|
12715
|
-
rdns.push(
|
|
13063
|
+
if (dn.organization) rdns.push(set2(seq(oid("2.5.4.10"), utf8(dn.organization))));
|
|
13064
|
+
rdns.push(set2(seq(oid("2.5.4.3"), utf8(dn.commonName))));
|
|
12716
13065
|
return seq(...rdns);
|
|
12717
13066
|
}
|
|
12718
13067
|
function extension(id2, critical, value) {
|
|
@@ -13347,9 +13696,9 @@ var WsHandles = class {
|
|
|
13347
13696
|
open = /* @__PURE__ */ new Map();
|
|
13348
13697
|
next;
|
|
13349
13698
|
local;
|
|
13350
|
-
constructor(transport,
|
|
13699
|
+
constructor(transport, next3, local) {
|
|
13351
13700
|
this.transport = transport;
|
|
13352
|
-
this.next =
|
|
13701
|
+
this.next = next3;
|
|
13353
13702
|
this.local = local;
|
|
13354
13703
|
}
|
|
13355
13704
|
owns(handle) {
|
|
@@ -13411,9 +13760,9 @@ var WsHandles = class {
|
|
|
13411
13760
|
}
|
|
13412
13761
|
async recv(socket, entry) {
|
|
13413
13762
|
try {
|
|
13414
|
-
const
|
|
13415
|
-
if (!
|
|
13416
|
-
return typeof
|
|
13763
|
+
const next3 = await entry.messages.next();
|
|
13764
|
+
if (!next3.done) {
|
|
13765
|
+
return typeof next3.value === "string" ? { ok: true, kind: "json", json: { text: next3.value } } : { ok: true, kind: "bytes", bytes: next3.value };
|
|
13417
13766
|
}
|
|
13418
13767
|
const closed = await socket.closed;
|
|
13419
13768
|
return {
|
|
@@ -13461,11 +13810,49 @@ var HTTP_OPS = [
|
|
|
13461
13810
|
"net-open",
|
|
13462
13811
|
"net-head",
|
|
13463
13812
|
"net-read",
|
|
13813
|
+
"net-write",
|
|
13814
|
+
"net-end",
|
|
13464
13815
|
"net-close",
|
|
13465
13816
|
"net-traits",
|
|
13466
13817
|
...WS_OPS
|
|
13467
13818
|
];
|
|
13468
|
-
var
|
|
13819
|
+
var Upload = class {
|
|
13820
|
+
queue = [];
|
|
13821
|
+
ended = false;
|
|
13822
|
+
wake;
|
|
13823
|
+
write(bytes) {
|
|
13824
|
+
if (this.ended) return Promise.resolve(false);
|
|
13825
|
+
return new Promise((taken) => {
|
|
13826
|
+
this.queue.push({ bytes, taken });
|
|
13827
|
+
this.wake?.();
|
|
13828
|
+
});
|
|
13829
|
+
}
|
|
13830
|
+
end() {
|
|
13831
|
+
this.ended = true;
|
|
13832
|
+
this.wake?.();
|
|
13833
|
+
}
|
|
13834
|
+
cancel() {
|
|
13835
|
+
this.ended = true;
|
|
13836
|
+
for (const { taken } of this.queue.splice(0)) taken(false);
|
|
13837
|
+
this.wake?.();
|
|
13838
|
+
}
|
|
13839
|
+
async *[Symbol.asyncIterator]() {
|
|
13840
|
+
for (; ; ) {
|
|
13841
|
+
const next3 = this.queue.shift();
|
|
13842
|
+
if (next3) {
|
|
13843
|
+
next3.taken(true);
|
|
13844
|
+
yield next3.bytes;
|
|
13845
|
+
continue;
|
|
13846
|
+
}
|
|
13847
|
+
if (this.ended) return;
|
|
13848
|
+
await new Promise((resolve2) => {
|
|
13849
|
+
this.wake = resolve2;
|
|
13850
|
+
});
|
|
13851
|
+
this.wake = void 0;
|
|
13852
|
+
}
|
|
13853
|
+
}
|
|
13854
|
+
};
|
|
13855
|
+
var EMPTY2 = new Uint8Array(0);
|
|
13469
13856
|
function message2(e) {
|
|
13470
13857
|
return e instanceof Error ? e.message : String(e);
|
|
13471
13858
|
}
|
|
@@ -13495,6 +13882,8 @@ var HttpHandles = class {
|
|
|
13495
13882
|
if (req.op === "net-open") return Promise.resolve(this.opened(req));
|
|
13496
13883
|
if (req.op === "net-head") return this.head(req.handle);
|
|
13497
13884
|
if (req.op === "net-read") return this.read(req.handle, req.max);
|
|
13885
|
+
if (req.op === "net-write") return this.write(req.handle, req.bytes);
|
|
13886
|
+
if (req.op === "net-end") return Promise.resolve(this.end(req.handle));
|
|
13498
13887
|
if (req.op === "net-traits") return Promise.resolve(this.traits(req.url));
|
|
13499
13888
|
return this.close(req.handle);
|
|
13500
13889
|
}
|
|
@@ -13513,19 +13902,37 @@ var HttpHandles = class {
|
|
|
13513
13902
|
return result;
|
|
13514
13903
|
}
|
|
13515
13904
|
opened(req) {
|
|
13905
|
+
if (req.stream && (this.local?.port(req.url) !== void 0 || !this.transport.traits.streamingBodies)) {
|
|
13906
|
+
return { ok: false, errno: "ENOTSUP", message: "this transport takes whole request bodies" };
|
|
13907
|
+
}
|
|
13516
13908
|
return { ok: true, kind: "json", json: this.start(req).handle };
|
|
13517
13909
|
}
|
|
13910
|
+
async write(handle, bytes) {
|
|
13911
|
+
const upload = this.open.get(handle)?.upload;
|
|
13912
|
+
if (!upload) return { ok: false, errno: "EBADF", message: `no upload ${handle}` };
|
|
13913
|
+
if (!await upload.write(bytes)) {
|
|
13914
|
+
return { ok: false, errno: "EPIPE", message: "the request no longer takes a body" };
|
|
13915
|
+
}
|
|
13916
|
+
return { ok: true, kind: "void" };
|
|
13917
|
+
}
|
|
13918
|
+
end(handle) {
|
|
13919
|
+
const upload = this.open.get(handle)?.upload;
|
|
13920
|
+
if (!upload) return { ok: false, errno: "EBADF", message: `no upload ${handle}` };
|
|
13921
|
+
upload.end();
|
|
13922
|
+
return { ok: true, kind: "void" };
|
|
13923
|
+
}
|
|
13518
13924
|
start(req) {
|
|
13519
13925
|
const handle = ++this.nextHandle;
|
|
13520
13926
|
const abort = new AbortController();
|
|
13521
13927
|
const entry = {
|
|
13522
13928
|
abort,
|
|
13523
13929
|
head: Promise.resolve({ ok: true, kind: "void" }),
|
|
13524
|
-
body: once(
|
|
13525
|
-
left:
|
|
13930
|
+
body: once(EMPTY2),
|
|
13931
|
+
left: EMPTY2,
|
|
13526
13932
|
done: false,
|
|
13527
13933
|
reading: Promise.resolve(),
|
|
13528
|
-
cancel: async () => void 0
|
|
13934
|
+
cancel: async () => void 0,
|
|
13935
|
+
...req.stream ? { upload: new Upload() } : {}
|
|
13529
13936
|
};
|
|
13530
13937
|
this.open.set(handle, entry);
|
|
13531
13938
|
entry.head = this.respond(handle, req, entry);
|
|
@@ -13539,7 +13946,7 @@ var HttpHandles = class {
|
|
|
13539
13946
|
url: target,
|
|
13540
13947
|
method: req.method,
|
|
13541
13948
|
headers: req.headers,
|
|
13542
|
-
...req.body ? { body: req.body } : {},
|
|
13949
|
+
...entry.upload ? { bodyStream: entry.upload } : req.body ? { body: req.body } : {},
|
|
13543
13950
|
signal: entry.abort.signal
|
|
13544
13951
|
};
|
|
13545
13952
|
const response = port === void 0 ? await this.transport.fetch(request, this.owner) : await this.local.fetch(request, port);
|
|
@@ -13550,6 +13957,7 @@ var HttpHandles = class {
|
|
|
13550
13957
|
const head = this.headOf(handle, shown, response);
|
|
13551
13958
|
return response.redirected ? { ...head, json: { ...head.json, redirected: true } } : head;
|
|
13552
13959
|
} catch (e) {
|
|
13960
|
+
entry.upload?.cancel();
|
|
13553
13961
|
const text = message2(e);
|
|
13554
13962
|
if (port !== void 0) return { ok: false, errno: codeOf2(e), message: text };
|
|
13555
13963
|
const status = e.status;
|
|
@@ -13586,9 +13994,9 @@ var HttpHandles = class {
|
|
|
13586
13994
|
async take(entry, max) {
|
|
13587
13995
|
if (entry.left.length === 0 && !entry.done) {
|
|
13588
13996
|
try {
|
|
13589
|
-
const
|
|
13590
|
-
if (
|
|
13591
|
-
else entry.left =
|
|
13997
|
+
const next3 = await entry.body.next();
|
|
13998
|
+
if (next3.done) entry.done = true;
|
|
13999
|
+
else entry.left = next3.value;
|
|
13592
14000
|
} catch (e) {
|
|
13593
14001
|
entry.done = true;
|
|
13594
14002
|
const timedOut = e?.code === "ETIMEDOUT";
|
|
@@ -13607,6 +14015,7 @@ var HttpHandles = class {
|
|
|
13607
14015
|
const entry = this.open.get(handle);
|
|
13608
14016
|
if (!entry) return { ok: false, errno: "EBADF", message: `no request ${handle}` };
|
|
13609
14017
|
this.open.delete(handle);
|
|
14018
|
+
entry.upload?.cancel();
|
|
13610
14019
|
entry.abort.abort();
|
|
13611
14020
|
await entry.cancel().catch(() => void 0);
|
|
13612
14021
|
return { ok: true, kind: "void" };
|
|
@@ -13961,12 +14370,12 @@ var KernelTty = class {
|
|
|
13961
14370
|
const chunks2 = [];
|
|
13962
14371
|
let n = 0;
|
|
13963
14372
|
while (this.readable.length > 0 && n < max) {
|
|
13964
|
-
const
|
|
13965
|
-
if (
|
|
13966
|
-
const take =
|
|
14373
|
+
const next3 = this.readable[0];
|
|
14374
|
+
if (next3 === null || next3 === void 0) break;
|
|
14375
|
+
const take = next3.subarray(0, max - n);
|
|
13967
14376
|
chunks2.push(take);
|
|
13968
14377
|
n += take.length;
|
|
13969
|
-
if (take.length <
|
|
14378
|
+
if (take.length < next3.length) this.readable[0] = next3.subarray(take.length);
|
|
13970
14379
|
else this.readable.shift();
|
|
13971
14380
|
if (this.canonical) break;
|
|
13972
14381
|
}
|
|
@@ -14063,11 +14472,11 @@ var PtyPair = class {
|
|
|
14063
14472
|
const chunks2 = [];
|
|
14064
14473
|
let n = 0;
|
|
14065
14474
|
while (this.queue.length > 0 && n < max - status) {
|
|
14066
|
-
const
|
|
14067
|
-
const take =
|
|
14475
|
+
const next3 = this.queue[0];
|
|
14476
|
+
const take = next3.subarray(0, max - status - n);
|
|
14068
14477
|
chunks2.push(take);
|
|
14069
14478
|
n += take.length;
|
|
14070
|
-
if (take.length <
|
|
14479
|
+
if (take.length < next3.length) this.queue[0] = next3.subarray(take.length);
|
|
14071
14480
|
else this.queue.shift();
|
|
14072
14481
|
}
|
|
14073
14482
|
const out = new Uint8Array(status + n);
|
|
@@ -14387,8 +14796,8 @@ var Semaphore = class {
|
|
|
14387
14796
|
this.mode = mode;
|
|
14388
14797
|
}
|
|
14389
14798
|
post() {
|
|
14390
|
-
const
|
|
14391
|
-
if (
|
|
14799
|
+
const next3 = this.waiters.shift();
|
|
14800
|
+
if (next3) next3.grant();
|
|
14392
14801
|
else if (this.value >= SEM_VALUE_MAX) throw new KernelError("EOVERFLOW");
|
|
14393
14802
|
else this.value++;
|
|
14394
14803
|
}
|
|
@@ -14816,9 +15225,9 @@ var VfsNode = class {
|
|
|
14816
15225
|
if (dirty && contents2 !== void 0) this.markDirty();
|
|
14817
15226
|
}
|
|
14818
15227
|
serial(op) {
|
|
14819
|
-
const
|
|
14820
|
-
this.queue =
|
|
14821
|
-
return
|
|
15228
|
+
const next3 = this.queue.then(op);
|
|
15229
|
+
this.queue = next3.catch(() => void 0);
|
|
15230
|
+
return next3;
|
|
14822
15231
|
}
|
|
14823
15232
|
revoke() {
|
|
14824
15233
|
this.revoked = true;
|
|
@@ -15240,9 +15649,9 @@ var VfsNodes = class {
|
|
|
15240
15649
|
}
|
|
15241
15650
|
for (const [p] of moved2) this.byPath.delete(p);
|
|
15242
15651
|
for (const [p, node] of moved2) {
|
|
15243
|
-
const
|
|
15244
|
-
if (node.path === p) node.renamedTo(
|
|
15245
|
-
this.byPath.set(
|
|
15652
|
+
const next3 = to + p.slice(from.length);
|
|
15653
|
+
if (node.path === p) node.renamedTo(next3);
|
|
15654
|
+
this.byPath.set(next3, node);
|
|
15246
15655
|
}
|
|
15247
15656
|
}
|
|
15248
15657
|
};
|
|
@@ -15617,6 +16026,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
15617
16026
|
"tty-pgrp-get",
|
|
15618
16027
|
"tty-pgrp-set",
|
|
15619
16028
|
"sig-mask",
|
|
16029
|
+
"sig-waiting",
|
|
15620
16030
|
"sig-pause",
|
|
15621
16031
|
...SOCKET_OPS,
|
|
15622
16032
|
...EPOLL_OPS,
|
|
@@ -15730,16 +16140,8 @@ var WasmProcess = class {
|
|
|
15730
16140
|
if (sig === SIG.STOP) return this.stop(sig);
|
|
15731
16141
|
const bit = sigbit(sig);
|
|
15732
16142
|
if (this.ignores(bit)) return "ignore";
|
|
15733
|
-
if (((this.options.blockedBits?.() ?? 0) & bit) !== 0) {
|
|
15734
|
-
|
|
15735
|
-
if (tid === void 0) {
|
|
15736
|
-
this.options.onPending?.(sig);
|
|
15737
|
-
return "deliver";
|
|
15738
|
-
}
|
|
15739
|
-
if (this.caught & bit) {
|
|
15740
|
-
this.options.threadKill?.(tid, sig);
|
|
15741
|
-
return "deliver";
|
|
15742
|
-
}
|
|
16143
|
+
if (((this.options.blockedBits?.() ?? 0) & bit) !== 0 && this.routeBlocked(sig, bit)) {
|
|
16144
|
+
return "deliver";
|
|
15743
16145
|
}
|
|
15744
16146
|
if (!(this.caught & bit)) {
|
|
15745
16147
|
const action = defaultAction(sig);
|
|
@@ -15756,6 +16158,17 @@ var WasmProcess = class {
|
|
|
15756
16158
|
blocked2.abort();
|
|
15757
16159
|
return "deliver";
|
|
15758
16160
|
}
|
|
16161
|
+
routeBlocked(sig, bit) {
|
|
16162
|
+
const waiter = this.waiterFor(bit);
|
|
16163
|
+
const tid = waiter ?? this.options.unblockedThread?.(sig);
|
|
16164
|
+
if (tid === void 0 || tid === 1) {
|
|
16165
|
+
this.options.onPending?.(sig);
|
|
16166
|
+
return true;
|
|
16167
|
+
}
|
|
16168
|
+
if (waiter === void 0 && !(this.caught & bit)) return false;
|
|
16169
|
+
this.options.threadKill?.(tid, sig);
|
|
16170
|
+
return true;
|
|
16171
|
+
}
|
|
15759
16172
|
async spawn(req) {
|
|
15760
16173
|
const { file, argv, argv0, env, cwd, chdir, stdio, inherit: inherit2, exec, pgid, session, deathSignal } = req;
|
|
15761
16174
|
if (deathSignal !== void 0 && (exec || !isSignal(deathSignal))) {
|
|
@@ -15836,6 +16249,16 @@ var WasmProcess = class {
|
|
|
15836
16249
|
}
|
|
15837
16250
|
blocks = /* @__PURE__ */ new WeakMap();
|
|
15838
16251
|
sizesRead = /* @__PURE__ */ new WeakMap();
|
|
16252
|
+
sigwaiters = /* @__PURE__ */ new Map();
|
|
16253
|
+
setSigwaiter(tid, set3) {
|
|
16254
|
+
if (set3 === 0) this.sigwaiters.delete(tid);
|
|
16255
|
+
else this.sigwaiters.set(tid, set3);
|
|
16256
|
+
}
|
|
16257
|
+
waiterFor(bit) {
|
|
16258
|
+
if (((this.sigwaiters.get(1) ?? 0) & bit) !== 0) return 1;
|
|
16259
|
+
for (const [tid, set3] of this.sigwaiters) if (set3 & bit) return tid;
|
|
16260
|
+
return void 0;
|
|
16261
|
+
}
|
|
15839
16262
|
async syscall(req, cancelled, block) {
|
|
15840
16263
|
this.options.onSyscall?.(req);
|
|
15841
16264
|
const started = performance.now();
|
|
@@ -16092,18 +16515,18 @@ var WasmProcess = class {
|
|
|
16092
16515
|
}
|
|
16093
16516
|
if (this.writesAt(req) && this.options.readonlyAt?.(path)) throw new KernelError("EROFS");
|
|
16094
16517
|
const open = { ...req, path };
|
|
16095
|
-
const
|
|
16518
|
+
const plain2 = this.plainMode(req.mode);
|
|
16096
16519
|
if (req.exclusive) {
|
|
16097
16520
|
await nodes.createExclusive(path, this.newOwner(req.mode));
|
|
16098
|
-
if (
|
|
16521
|
+
if (plain2 !== void 0) await fs.chmod?.(path, plain2);
|
|
16099
16522
|
this.fds.installAt(fd, this.openVfsFile(open, void 0, fs));
|
|
16100
16523
|
} else if (req.create) {
|
|
16101
16524
|
await nodes.onEntry(path, async () => {
|
|
16102
|
-
const marks = this.options.owners ||
|
|
16525
|
+
const marks = this.options.owners || plain2 !== void 0;
|
|
16103
16526
|
const fresh2 = marks && !await present2(fs, path, true);
|
|
16104
16527
|
this.fds.installAt(fd, this.openVfsFile(open, await nodes.identify(path), fs));
|
|
16105
16528
|
await this.fds.get(fd).file.stat?.();
|
|
16106
|
-
if (fresh2 &&
|
|
16529
|
+
if (fresh2 && plain2 !== void 0) await fs.chmod?.(path, plain2);
|
|
16107
16530
|
else if (fresh2) {
|
|
16108
16531
|
await fs.chown?.(path, { ...this.newOwner(req.mode), kind: "new" });
|
|
16109
16532
|
}
|
|
@@ -16744,6 +17167,9 @@ var WasmProcess = class {
|
|
|
16744
17167
|
case "dl-unlock":
|
|
16745
17168
|
this.unlockDl(req.owner);
|
|
16746
17169
|
return { ok: true, kind: "void" };
|
|
17170
|
+
case "sig-waiting":
|
|
17171
|
+
this.setSigwaiter(req.tid, req.set);
|
|
17172
|
+
return { ok: true, kind: "void" };
|
|
16747
17173
|
case "sig-mask":
|
|
16748
17174
|
this.caught = req.caught;
|
|
16749
17175
|
this.ignored = req.ignored;
|
|
@@ -16811,8 +17237,8 @@ var WasmProcess = class {
|
|
|
16811
17237
|
};
|
|
16812
17238
|
withDl(state) {
|
|
16813
17239
|
if (this.dlLog.length === 0) return state;
|
|
16814
|
-
const { next:
|
|
16815
|
-
const dl = { log: [...this.dlLog], next:
|
|
17240
|
+
const { next: next3, handle, free, live } = this.closures;
|
|
17241
|
+
const dl = { log: [...this.dlLog], next: next3, handle, free: [...free], live: [...live] };
|
|
16816
17242
|
return { ...state, dl };
|
|
16817
17243
|
}
|
|
16818
17244
|
seedDl(dl) {
|
|
@@ -16823,8 +17249,8 @@ var WasmProcess = class {
|
|
|
16823
17249
|
this.closures.free.push(...dl.free);
|
|
16824
17250
|
for (const index of dl.live) this.closures.live.add(index);
|
|
16825
17251
|
}
|
|
16826
|
-
allocateClosure(
|
|
16827
|
-
const index = this.closures.free.pop() ?? Math.max(
|
|
17252
|
+
allocateClosure(floor2) {
|
|
17253
|
+
const index = this.closures.free.pop() ?? Math.max(floor2, this.closures.next);
|
|
16828
17254
|
this.closures.next = Math.max(this.closures.next, index + 1);
|
|
16829
17255
|
this.closures.live.add(index);
|
|
16830
17256
|
this.dlLog.push({ kind: "closure", index });
|
|
@@ -16876,8 +17302,8 @@ var WasmProcess = class {
|
|
|
16876
17302
|
wakeDl() {
|
|
16877
17303
|
for (const waiter of [...this.dlLock.waiters]) waiter.wake(false);
|
|
16878
17304
|
}
|
|
16879
|
-
reserveSlots(
|
|
16880
|
-
const base = Math.max(
|
|
17305
|
+
reserveSlots(floor2, size) {
|
|
17306
|
+
const base = Math.max(floor2, this.closures.next);
|
|
16881
17307
|
this.closures.next = base + size;
|
|
16882
17308
|
return base;
|
|
16883
17309
|
}
|
|
@@ -16934,6 +17360,7 @@ var WASM_MAX_THREADS = 256;
|
|
|
16934
17360
|
// src/kernel/host.ts
|
|
16935
17361
|
var CRASHED = 70;
|
|
16936
17362
|
var KILL_GRACE_MS = 2e3;
|
|
17363
|
+
var KILL_HARD_MS = 5e3;
|
|
16937
17364
|
var descIds = /* @__PURE__ */ new WeakMap();
|
|
16938
17365
|
var nextDescId = 1;
|
|
16939
17366
|
function descId(file) {
|
|
@@ -16960,16 +17387,21 @@ function inheritedFds(fds) {
|
|
|
16960
17387
|
var Dying = class {
|
|
16961
17388
|
ending;
|
|
16962
17389
|
timer;
|
|
17390
|
+
hard;
|
|
16963
17391
|
busy = 0;
|
|
16964
17392
|
finish;
|
|
16965
17393
|
start(code, sig, header4, process2, finish) {
|
|
16966
17394
|
if (this.ending) return;
|
|
16967
17395
|
this.ending = { code, sig };
|
|
16968
17396
|
this.finish = finish;
|
|
17397
|
+
this.hard = setTimeout(finish, KILL_HARD_MS);
|
|
16969
17398
|
this.arm();
|
|
16970
17399
|
Atomics.store(header4, SAB_I_KILLED, code);
|
|
16971
17400
|
process2.die();
|
|
16972
17401
|
}
|
|
17402
|
+
serve(req, work) {
|
|
17403
|
+
return this.ending && isWasmSyscall(req) ? work() : this.serving(work);
|
|
17404
|
+
}
|
|
16973
17405
|
async serving(work) {
|
|
16974
17406
|
this.busy++;
|
|
16975
17407
|
clearTimeout(this.timer);
|
|
@@ -16986,6 +17418,7 @@ var Dying = class {
|
|
|
16986
17418
|
}
|
|
16987
17419
|
clear() {
|
|
16988
17420
|
clearTimeout(this.timer);
|
|
17421
|
+
clearTimeout(this.hard);
|
|
16989
17422
|
}
|
|
16990
17423
|
status(reported2) {
|
|
16991
17424
|
if (this.ending) return [this.ending.code, this.ending.sig];
|
|
@@ -16997,8 +17430,8 @@ function killThread(thread, caught, sig) {
|
|
|
16997
17430
|
const held = (Atomics.load(thread.header, SAB_I_BLOCKED) & sigbit(sig)) !== 0;
|
|
16998
17431
|
if (!held && (caught & sigbit(sig)) === 0) return false;
|
|
16999
17432
|
Atomics.or(thread.header, SAB_I_SIGNALS, sigbit(sig));
|
|
17000
|
-
if (held) return true;
|
|
17001
17433
|
Atomics.notify(thread.header, SAB_I_SIGNALS);
|
|
17434
|
+
if (held) return true;
|
|
17002
17435
|
const blocked2 = thread.interrupt;
|
|
17003
17436
|
thread.interrupt = new AbortController();
|
|
17004
17437
|
blocked2.abort();
|
|
@@ -17094,7 +17527,7 @@ function inherited(opts) {
|
|
|
17094
17527
|
...opts.cred ? { cred: opts.cred } : {}
|
|
17095
17528
|
};
|
|
17096
17529
|
}
|
|
17097
|
-
function holdingToken(opts,
|
|
17530
|
+
function holdingToken(opts, holds2, caller) {
|
|
17098
17531
|
return mintSyncFsToken({
|
|
17099
17532
|
...opts.owners ? caller : { umask: caller.umask },
|
|
17100
17533
|
...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
|
|
@@ -17105,13 +17538,13 @@ function holdingToken(opts, holds, caller) {
|
|
|
17105
17538
|
noLinks: opts.noLinks,
|
|
17106
17539
|
cwd: opts.cwd,
|
|
17107
17540
|
...opts.statfs ? { statfs: opts.statfs } : {},
|
|
17108
|
-
hold: (path, on, open, real, handle) =>
|
|
17109
|
-
keptFor: (handle) =>
|
|
17110
|
-
unlinked: (path) =>
|
|
17111
|
-
gate: (path, op) => opts.unlinkGate &&
|
|
17112
|
-
own: (path, op) =>
|
|
17113
|
-
revoked: (path) =>
|
|
17114
|
-
renamed: (from, to) =>
|
|
17541
|
+
hold: (path, on, open, real, handle) => holds2.hold(path, on, open, real, handle),
|
|
17542
|
+
keptFor: (handle) => holds2.keptFor(handle),
|
|
17543
|
+
unlinked: (path) => holds2.keptAt(path),
|
|
17544
|
+
gate: (path, op) => opts.unlinkGate && holds2.holding(path) ? opts.unlinkGate.run(holds2.keyOf(path), op) : op(),
|
|
17545
|
+
own: (path, op) => holds2.own(path, op),
|
|
17546
|
+
revoked: (path) => holds2.isRevoked(path),
|
|
17547
|
+
renamed: (from, to) => holds2.renamed(from, to)
|
|
17115
17548
|
});
|
|
17116
17549
|
}
|
|
17117
17550
|
function linksOf(opts) {
|
|
@@ -17185,6 +17618,9 @@ function threadInit(opts, program, sab, cred, thread, main) {
|
|
|
17185
17618
|
signals: main
|
|
17186
17619
|
};
|
|
17187
17620
|
}
|
|
17621
|
+
function settleExit(exit, settle, code) {
|
|
17622
|
+
void exit.catch(() => void 0).then(() => settle(code & 255));
|
|
17623
|
+
}
|
|
17188
17624
|
function spawnWasmProcess(opts) {
|
|
17189
17625
|
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
17190
17626
|
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
@@ -17211,19 +17647,20 @@ function spawnWasmProcess(opts) {
|
|
|
17211
17647
|
)
|
|
17212
17648
|
);
|
|
17213
17649
|
publishStops(process2, header4);
|
|
17214
|
-
const
|
|
17215
|
-
opts.held?.add(
|
|
17216
|
-
const token = holdingToken(opts,
|
|
17650
|
+
const holds2 = new HeldPaths();
|
|
17651
|
+
opts.held?.add(holds2);
|
|
17652
|
+
const token = holdingToken(opts, holds2, {
|
|
17217
17653
|
cred: () => process2.cred,
|
|
17218
17654
|
umask: () => process2.umask,
|
|
17219
17655
|
created: created3,
|
|
17220
|
-
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (
|
|
17656
|
+
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds2.keeps(path) || await process2.holds(path))
|
|
17221
17657
|
});
|
|
17222
|
-
process2.keptPath = (path) =>
|
|
17223
|
-
process2.keptHandle = (handle2) =>
|
|
17658
|
+
process2.keptPath = (path) => holds2.keptAt(path)?.hidden;
|
|
17659
|
+
process2.keptHandle = (handle2) => holds2.keptFor(handle2)?.hidden;
|
|
17224
17660
|
const worker = opts.createWorker();
|
|
17225
17661
|
const dying = new Dying();
|
|
17226
|
-
const dispatch2 = (req, block) => dying.
|
|
17662
|
+
const dispatch2 = (req, block) => dying.serve(
|
|
17663
|
+
req,
|
|
17227
17664
|
() => isWasmSyscall(req) ? process2.syscall(req, void 0, block) : dispatchSyncFs(req)
|
|
17228
17665
|
);
|
|
17229
17666
|
const clocks = new ProcessClocks(sab, opts.program.abi !== "js", process2);
|
|
@@ -17246,12 +17683,9 @@ function spawnWasmProcess(opts) {
|
|
|
17246
17683
|
responder.dispose();
|
|
17247
17684
|
lane?.dispose();
|
|
17248
17685
|
revokeSyncFsToken(token);
|
|
17249
|
-
opts.held?.delete(
|
|
17686
|
+
opts.held?.delete(holds2);
|
|
17250
17687
|
worker.terminate();
|
|
17251
|
-
|
|
17252
|
-
() => settle(code),
|
|
17253
|
-
() => settle(code)
|
|
17254
|
-
);
|
|
17688
|
+
settleExit(process2.exit(), settle, code);
|
|
17255
17689
|
};
|
|
17256
17690
|
const exitNow = (code) => {
|
|
17257
17691
|
queueMicrotask(() => finish(...dying.status(code)));
|
|
@@ -17295,7 +17729,7 @@ function spawnWasmProcess(opts) {
|
|
|
17295
17729
|
const tsignals = threadSignalsOf(tsab);
|
|
17296
17730
|
if (thread.blocked) storeBlocked(tsignals.header, thread.blocked);
|
|
17297
17731
|
threadSignals.set(thread.tid, tsignals);
|
|
17298
|
-
const tdispatch = (req, block) => dying.
|
|
17732
|
+
const tdispatch = (req, block) => dying.serve(req, () => threadCall(process2, req, threadCancel(tsignals), block));
|
|
17299
17733
|
const tresponder = attachSyncSabResponder(tw, tsab, token, {
|
|
17300
17734
|
dispatch: clocks.timed(clocks.thread(thread.tid, tsab), tdispatch)
|
|
17301
17735
|
});
|
|
@@ -17765,10 +18199,10 @@ var Automaton = class {
|
|
|
17765
18199
|
let node = 0;
|
|
17766
18200
|
for (const byte of bytes) {
|
|
17767
18201
|
const key = node * 256 + byte;
|
|
17768
|
-
let
|
|
17769
|
-
if (
|
|
17770
|
-
|
|
17771
|
-
this.edges.set(key,
|
|
18202
|
+
let next3 = this.edges.get(key);
|
|
18203
|
+
if (next3 === void 0) {
|
|
18204
|
+
next3 = this.depth.length;
|
|
18205
|
+
this.edges.set(key, next3);
|
|
17772
18206
|
this.fail.push(0);
|
|
17773
18207
|
this.depth.push(this.depth[node] + 1);
|
|
17774
18208
|
this.children.push(0);
|
|
@@ -17776,7 +18210,7 @@ var Automaton = class {
|
|
|
17776
18210
|
this.out.push([]);
|
|
17777
18211
|
this.dict.push(-1);
|
|
17778
18212
|
}
|
|
17779
|
-
node =
|
|
18213
|
+
node = next3;
|
|
17780
18214
|
}
|
|
17781
18215
|
const id2 = this.lengths.length;
|
|
17782
18216
|
this.lengths.push(bytes.length);
|
|
@@ -17812,8 +18246,8 @@ var Automaton = class {
|
|
|
17812
18246
|
step(state, byte) {
|
|
17813
18247
|
let current = state;
|
|
17814
18248
|
for (; ; ) {
|
|
17815
|
-
const
|
|
17816
|
-
if (
|
|
18249
|
+
const next3 = this.edges.get(current * 256 + byte);
|
|
18250
|
+
if (next3 !== void 0) return next3;
|
|
17817
18251
|
if (current === 0) return 0;
|
|
17818
18252
|
current = this.fail[current];
|
|
17819
18253
|
}
|
|
@@ -17841,7 +18275,7 @@ var RANK = {
|
|
|
17841
18275
|
};
|
|
17842
18276
|
var CR2 = 13;
|
|
17843
18277
|
var LF2 = 10;
|
|
17844
|
-
var
|
|
18278
|
+
var EMPTY3 = new Uint8Array(0);
|
|
17845
18279
|
function register(automaton, sources, ids, bytes, source) {
|
|
17846
18280
|
const key = Array.from(bytes).join(",");
|
|
17847
18281
|
let id2 = ids.get(key);
|
|
@@ -17967,7 +18401,7 @@ function pass(c, input, final) {
|
|
|
17967
18401
|
const partials = [];
|
|
17968
18402
|
scanMain(c, input, best, partials);
|
|
17969
18403
|
scanWrapped(c, input, best, partials);
|
|
17970
|
-
const
|
|
18404
|
+
const holds2 = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
|
|
17971
18405
|
const starts = [...best.keys()].sort((a, b) => a - b);
|
|
17972
18406
|
const parts2 = [];
|
|
17973
18407
|
const hits = /* @__PURE__ */ new Map();
|
|
@@ -17977,16 +18411,16 @@ function pass(c, input, final) {
|
|
|
17977
18411
|
let h = 0;
|
|
17978
18412
|
for (; ; ) {
|
|
17979
18413
|
while (s < starts.length && starts[s] < pos) s++;
|
|
17980
|
-
while (h <
|
|
17981
|
-
const hold = h <
|
|
17982
|
-
const
|
|
17983
|
-
if (hold <=
|
|
18414
|
+
while (h < holds2.length && holds2[h] < pos) h++;
|
|
18415
|
+
const hold = h < holds2.length ? holds2[h] : Infinity;
|
|
18416
|
+
const next3 = s < starts.length ? starts[s] : Infinity;
|
|
18417
|
+
if (hold <= next3) {
|
|
17984
18418
|
cut = Math.min(hold, input.length);
|
|
17985
18419
|
break;
|
|
17986
18420
|
}
|
|
17987
|
-
const candidate = best.get(
|
|
18421
|
+
const candidate = best.get(next3);
|
|
17988
18422
|
parts2.push(
|
|
17989
|
-
input.subarray(pos,
|
|
18423
|
+
input.subarray(pos, next3),
|
|
17990
18424
|
c.replacements[candidate.secret][candidate.form === "raw" ? 0 : 1]
|
|
17991
18425
|
);
|
|
17992
18426
|
count(c, hits, candidate);
|
|
@@ -18021,12 +18455,12 @@ function compile(secrets, options = {}) {
|
|
|
18021
18455
|
return { text: decoder4.decode(bytes), hits };
|
|
18022
18456
|
},
|
|
18023
18457
|
stream() {
|
|
18024
|
-
let pending =
|
|
18458
|
+
let pending = EMPTY3;
|
|
18025
18459
|
const hits = /* @__PURE__ */ new Map();
|
|
18026
18460
|
const run2 = (final) => {
|
|
18027
18461
|
if (c.secrets.length === 0 || pending.length === 0) {
|
|
18028
18462
|
const out = pending;
|
|
18029
|
-
pending =
|
|
18463
|
+
pending = EMPTY3;
|
|
18030
18464
|
return out;
|
|
18031
18465
|
}
|
|
18032
18466
|
const result = pass(c, pending, final);
|
|
@@ -18040,7 +18474,7 @@ function compile(secrets, options = {}) {
|
|
|
18040
18474
|
return run2(false);
|
|
18041
18475
|
},
|
|
18042
18476
|
idle() {
|
|
18043
|
-
return pending.length < FRAGMENT ? run2(true) :
|
|
18477
|
+
return pending.length < FRAGMENT ? run2(true) : EMPTY3;
|
|
18044
18478
|
},
|
|
18045
18479
|
end() {
|
|
18046
18480
|
return run2(true);
|
|
@@ -18082,7 +18516,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
18082
18516
|
let timer;
|
|
18083
18517
|
let failed3;
|
|
18084
18518
|
const waiters = /* @__PURE__ */ new Set();
|
|
18085
|
-
const
|
|
18519
|
+
const quiet3 = () => !busy && pending === 0;
|
|
18086
18520
|
const wake = () => {
|
|
18087
18521
|
for (const waiter of [...waiters]) waiter();
|
|
18088
18522
|
};
|
|
@@ -18099,7 +18533,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
18099
18533
|
if (failed3 === void 0) failed3 = err;
|
|
18100
18534
|
}).finally(() => {
|
|
18101
18535
|
pending -= 1;
|
|
18102
|
-
if (
|
|
18536
|
+
if (quiet3()) wake();
|
|
18103
18537
|
});
|
|
18104
18538
|
};
|
|
18105
18539
|
const settling = (signal) => new Promise((resolve2, reject) => {
|
|
@@ -18117,7 +18551,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
18117
18551
|
signal?.addEventListener("abort", stop, { once: true });
|
|
18118
18552
|
});
|
|
18119
18553
|
const settled = async () => {
|
|
18120
|
-
while (!
|
|
18554
|
+
while (!quiet3()) await settling();
|
|
18121
18555
|
};
|
|
18122
18556
|
const changed = async (signal) => {
|
|
18123
18557
|
const round = new AbortController();
|
|
@@ -18133,7 +18567,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
18133
18567
|
};
|
|
18134
18568
|
const turn = async (signal) => {
|
|
18135
18569
|
for (let waited = false; ; waited = true) {
|
|
18136
|
-
if (
|
|
18570
|
+
if (quiet3() && (pollFile(file).writable || !file.changed)) {
|
|
18137
18571
|
busy = true;
|
|
18138
18572
|
return;
|
|
18139
18573
|
}
|
|
@@ -18162,7 +18596,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
18162
18596
|
...bound(file, "stat"),
|
|
18163
18597
|
poll: () => {
|
|
18164
18598
|
const state = pollFile(file);
|
|
18165
|
-
return
|
|
18599
|
+
return quiet3() ? state : { ...state, writable: false };
|
|
18166
18600
|
},
|
|
18167
18601
|
changed,
|
|
18168
18602
|
...file.tty ? { tty: file.tty } : {},
|
|
@@ -18178,7 +18612,7 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
18178
18612
|
await send(stream2.push(taken), signal);
|
|
18179
18613
|
} finally {
|
|
18180
18614
|
busy = false;
|
|
18181
|
-
if (
|
|
18615
|
+
if (quiet3()) wake();
|
|
18182
18616
|
}
|
|
18183
18617
|
timer = setTimeout(release, idleMs);
|
|
18184
18618
|
return taken.length;
|
|
@@ -18279,15 +18713,15 @@ function isRecord(value) {
|
|
|
18279
18713
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18280
18714
|
}
|
|
18281
18715
|
function serialized(reply) {
|
|
18282
|
-
let
|
|
18716
|
+
let plain2;
|
|
18283
18717
|
try {
|
|
18284
18718
|
const text = JSON.stringify(reply);
|
|
18285
|
-
|
|
18719
|
+
plain2 = text === void 0 ? void 0 : JSON.parse(text);
|
|
18286
18720
|
} catch (err) {
|
|
18287
18721
|
return JSON.stringify(errorReply("EIO", lineOf2(err)));
|
|
18288
18722
|
}
|
|
18289
|
-
if (!isRecord(
|
|
18290
|
-
const { v: _, ...rest2 } =
|
|
18723
|
+
if (!isRecord(plain2)) return JSON.stringify(errorReply("EIO", "the vault gave no reply"));
|
|
18724
|
+
const { v: _, ...rest2 } = plain2;
|
|
18291
18725
|
return JSON.stringify({ v: 1, ...rest2 });
|
|
18292
18726
|
}
|
|
18293
18727
|
function lineOf2(err) {
|
|
@@ -19306,22 +19740,22 @@ function keepWatching(loop, signal) {
|
|
|
19306
19740
|
const stop = () => session2.abort();
|
|
19307
19741
|
signal.addEventListener("abort", stop);
|
|
19308
19742
|
let timer;
|
|
19309
|
-
const
|
|
19743
|
+
const quiet3 = () => {
|
|
19310
19744
|
clearTimeout(timer);
|
|
19311
19745
|
timer = setTimeout(stop, silenceMs);
|
|
19312
19746
|
};
|
|
19313
19747
|
let opened2 = false;
|
|
19314
19748
|
try {
|
|
19315
19749
|
const client = await loop.connect();
|
|
19316
|
-
|
|
19750
|
+
quiet3();
|
|
19317
19751
|
await client.watch(
|
|
19318
19752
|
session2.signal,
|
|
19319
19753
|
(event) => {
|
|
19320
|
-
|
|
19754
|
+
quiet3();
|
|
19321
19755
|
if (!event.ping) loop.event(event);
|
|
19322
19756
|
},
|
|
19323
19757
|
() => {
|
|
19324
|
-
|
|
19758
|
+
quiet3();
|
|
19325
19759
|
opened2 = true;
|
|
19326
19760
|
up = true;
|
|
19327
19761
|
loop.up(client);
|
|
@@ -19866,9 +20300,9 @@ function tmpfs() {
|
|
|
19866
20300
|
let node = root;
|
|
19867
20301
|
for (const name2 of parts2(path)) {
|
|
19868
20302
|
if (node.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
19869
|
-
const
|
|
19870
|
-
if (!
|
|
19871
|
-
node =
|
|
20303
|
+
const next3 = node.children.get(name2);
|
|
20304
|
+
if (!next3) throw fsError2("ENOENT", path);
|
|
20305
|
+
node = next3;
|
|
19872
20306
|
}
|
|
19873
20307
|
return node;
|
|
19874
20308
|
}
|
|
@@ -20174,6 +20608,28 @@ function foreignImports(bytes) {
|
|
|
20174
20608
|
return {};
|
|
20175
20609
|
}
|
|
20176
20610
|
|
|
20611
|
+
// src/refused-command.ts
|
|
20612
|
+
var REFUSED_PATH = "/usr/lib/slicc/refused";
|
|
20613
|
+
var REFUSED_SOURCE = [
|
|
20614
|
+
"export default async function refused(ctx) {",
|
|
20615
|
+
" await ctx.write(2, ctx.argv[1] + '\\n').catch(() => undefined);",
|
|
20616
|
+
" return 126;",
|
|
20617
|
+
"}"
|
|
20618
|
+
].join("\n");
|
|
20619
|
+
function refusing(command) {
|
|
20620
|
+
if (!command.refused) return command;
|
|
20621
|
+
return {
|
|
20622
|
+
name: command.name,
|
|
20623
|
+
abi: "js",
|
|
20624
|
+
glue: REFUSED_PATH,
|
|
20625
|
+
wasm: REFUSED_PATH,
|
|
20626
|
+
argv0: command.name,
|
|
20627
|
+
args: [`${command.name}: ${command.refused}`],
|
|
20628
|
+
refused: command.refused,
|
|
20629
|
+
shows: command.script ?? command.wasm
|
|
20630
|
+
};
|
|
20631
|
+
}
|
|
20632
|
+
|
|
20177
20633
|
// src/sudo.ts
|
|
20178
20634
|
var SUDOERS = "/etc/sudoers";
|
|
20179
20635
|
var SUDOERS_D = "/etc/sudoers.d";
|
|
@@ -20201,13 +20657,13 @@ function splitWords(text) {
|
|
|
20201
20657
|
while (piece.lastIndex < text.length) {
|
|
20202
20658
|
const m = piece.exec(text);
|
|
20203
20659
|
if (!m) return void 0;
|
|
20204
|
-
const [, single, double, escaped,
|
|
20660
|
+
const [, single, double, escaped, plain2, space] = m;
|
|
20205
20661
|
if (space !== void 0) {
|
|
20206
20662
|
if (word !== void 0) words2.push(word);
|
|
20207
20663
|
word = void 0;
|
|
20208
20664
|
continue;
|
|
20209
20665
|
}
|
|
20210
|
-
word = (word ?? "") + (single ?? (double !== void 0 ? unescaped(double) : escaped ??
|
|
20666
|
+
word = (word ?? "") + (single ?? (double !== void 0 ? unescaped(double) : escaped ?? plain2));
|
|
20211
20667
|
}
|
|
20212
20668
|
if (word !== void 0) words2.push(word);
|
|
20213
20669
|
return words2;
|
|
@@ -20239,7 +20695,7 @@ function parseRule(line) {
|
|
|
20239
20695
|
if (!cmnd?.[0]?.startsWith("/")) return void 0;
|
|
20240
20696
|
return { ...rule, cmnd };
|
|
20241
20697
|
}
|
|
20242
|
-
function flags(parsed2, arg,
|
|
20698
|
+
function flags(parsed2, arg, next3) {
|
|
20243
20699
|
for (let j = 1; j < arg.length; j++) {
|
|
20244
20700
|
const flag = arg[j];
|
|
20245
20701
|
if (flag === "n") parsed2.nonInteractive = true;
|
|
@@ -20247,7 +20703,7 @@ function flags(parsed2, arg, next2) {
|
|
|
20247
20703
|
else if (flag !== "u") return `sudo: invalid option -- '${flag}'
|
|
20248
20704
|
${USAGE}`;
|
|
20249
20705
|
else {
|
|
20250
|
-
const user = arg.slice(j + 1) ||
|
|
20706
|
+
const user = arg.slice(j + 1) || next3;
|
|
20251
20707
|
if (!user) return `sudo: option requires an argument -- 'u'
|
|
20252
20708
|
${USAGE}`;
|
|
20253
20709
|
parsed2.user = user;
|
|
@@ -20697,9 +21153,9 @@ function appendedRoots(given) {
|
|
|
20697
21153
|
return [...roots];
|
|
20698
21154
|
}
|
|
20699
21155
|
function plainEnv(words2) {
|
|
20700
|
-
const
|
|
20701
|
-
if (baseName2(words2[0] ?? "") !== "env" ||
|
|
20702
|
-
return
|
|
21156
|
+
const next3 = words2[1];
|
|
21157
|
+
if (baseName2(words2[0] ?? "") !== "env" || next3 === void 0) return false;
|
|
21158
|
+
return next3 === "-S" || !next3.startsWith("-") && !next3.includes("=");
|
|
20703
21159
|
}
|
|
20704
21160
|
function shebangCommand(words2) {
|
|
20705
21161
|
if (!plainEnv(words2)) {
|
|
@@ -20723,9 +21179,9 @@ function expandDefaults(defaults, env) {
|
|
|
20723
21179
|
for (const [key, value] of Object.entries(defaults ?? {})) {
|
|
20724
21180
|
let missing4 = false;
|
|
20725
21181
|
const expanded = value.replace(ENV_REFERENCE, (_, name2) => {
|
|
20726
|
-
const
|
|
20727
|
-
if (
|
|
20728
|
-
return
|
|
21182
|
+
const set3 = Object.hasOwn(env, name2) ? env[name2] : void 0;
|
|
21183
|
+
if (set3 === void 0) missing4 = true;
|
|
21184
|
+
return set3 ?? "";
|
|
20729
21185
|
});
|
|
20730
21186
|
if (!missing4) out[key] = expanded;
|
|
20731
21187
|
}
|
|
@@ -20950,7 +21406,7 @@ var Launcher = class {
|
|
|
20950
21406
|
const holders = [this.held, this.openFiles];
|
|
20951
21407
|
this.unlinked = new UnlinkedKeeper(
|
|
20952
21408
|
fs,
|
|
20953
|
-
{ [Symbol.iterator]: () => holders.flatMap((
|
|
21409
|
+
{ [Symbol.iterator]: () => holders.flatMap((set3) => [...set3]).values() },
|
|
20954
21410
|
(path) => this.mountRoot(path),
|
|
20955
21411
|
{
|
|
20956
21412
|
locks: webLocks(),
|
|
@@ -21035,11 +21491,21 @@ var Launcher = class {
|
|
|
21035
21491
|
found = this.trustedAppended().then(async (appended2) => {
|
|
21036
21492
|
const tiers = await this.tiers(scope, appended2);
|
|
21037
21493
|
return scanCommands(this.scanned, tiers, tiers.length - appended2.length);
|
|
21038
|
-
}).then((commands) => commands.set(SUDO_COMMAND.name, SUDO_COMMAND));
|
|
21494
|
+
}).then((commands) => this.refusals(commands).set(SUDO_COMMAND.name, SUDO_COMMAND));
|
|
21039
21495
|
this.catalogs.set(scope, found);
|
|
21040
21496
|
}
|
|
21041
21497
|
return found;
|
|
21042
21498
|
}
|
|
21499
|
+
refusals(commands) {
|
|
21500
|
+
for (const [name2, command] of commands) {
|
|
21501
|
+
if (!command.refused) continue;
|
|
21502
|
+
commands.set(name2, refusing(command));
|
|
21503
|
+
if (this.warned.has(command.refused)) continue;
|
|
21504
|
+
this.warned.add(command.refused);
|
|
21505
|
+
console.warn(`slicc-kernel: refusing the commands of ${command.refused}`);
|
|
21506
|
+
}
|
|
21507
|
+
return commands;
|
|
21508
|
+
}
|
|
21043
21509
|
ownCommands(scope) {
|
|
21044
21510
|
let found = this.ownCatalogs.get(scope);
|
|
21045
21511
|
if (!found) {
|
|
@@ -21114,7 +21580,8 @@ var Launcher = class {
|
|
|
21114
21580
|
);
|
|
21115
21581
|
return {
|
|
21116
21582
|
byUid: new Map(users.map((account, i) => [account.uid, homes[i]])),
|
|
21117
|
-
byBin: new Map(homes.map((home) => [`${home}/bin`, home]))
|
|
21583
|
+
byBin: new Map(homes.map((home) => [`${home}/bin`, home])),
|
|
21584
|
+
owners: new Map(homes.map((home, i) => [home, credOf(users[i])]))
|
|
21118
21585
|
};
|
|
21119
21586
|
},
|
|
21120
21587
|
() => ({ byUid: /* @__PURE__ */ new Map(), byBin: /* @__PURE__ */ new Map() })
|
|
@@ -21456,12 +21923,12 @@ var Launcher = class {
|
|
|
21456
21923
|
return `${path}:${st.size}:${st.mtime.getTime()}`;
|
|
21457
21924
|
}
|
|
21458
21925
|
verified(path, caller, fs = this.base) {
|
|
21459
|
-
const
|
|
21460
|
-
return this.integrity ? this.integrity.read(path, caller,
|
|
21926
|
+
const plain2 = () => fs.readFileBuffer(path);
|
|
21927
|
+
return this.integrity ? this.integrity.read(path, caller, plain2) : plain2();
|
|
21461
21928
|
}
|
|
21462
21929
|
keyed(path, caller, asked) {
|
|
21463
|
-
const
|
|
21464
|
-
return this.integrity ? this.integrity.readKeyed(path, caller,
|
|
21930
|
+
const plain2 = async () => this.base.readFileBuffer(path);
|
|
21931
|
+
return this.integrity ? this.integrity.readKeyed(path, caller, plain2, asked) : plain2().then((bytes) => ({ bytes }));
|
|
21465
21932
|
}
|
|
21466
21933
|
cached(cache, key, load) {
|
|
21467
21934
|
const hit = cache.get(key);
|
|
@@ -21532,6 +21999,9 @@ var Launcher = class {
|
|
|
21532
21999
|
if (target.abi === "js" && target.wasm === SUDO_PATH) {
|
|
21533
22000
|
return { abi: "js", glue: SUDO_SOURCE, path: SUDO_PATH };
|
|
21534
22001
|
}
|
|
22002
|
+
if (target.abi === "js" && target.wasm === REFUSED_PATH) {
|
|
22003
|
+
return { abi: "js", glue: REFUSED_SOURCE, path: REFUSED_PATH };
|
|
22004
|
+
}
|
|
21535
22005
|
const { asked } = target;
|
|
21536
22006
|
if (target.abi === "js") {
|
|
21537
22007
|
return { abi: "js", glue: await this.text(target.wasm, caller, asked), path: target.wasm };
|
|
@@ -21601,7 +22071,7 @@ var Launcher = class {
|
|
|
21601
22071
|
});
|
|
21602
22072
|
return {
|
|
21603
22073
|
source: {
|
|
21604
|
-
read: (path,
|
|
22074
|
+
read: (path, plain2) => integrity.readSource(path, caller(), plain2),
|
|
21605
22075
|
open: (path, real) => integrity.openSource(path, caller(), real)
|
|
21606
22076
|
}
|
|
21607
22077
|
};
|
|
@@ -22040,9 +22510,9 @@ var Launcher = class {
|
|
|
22040
22510
|
const members = this.jobs.list();
|
|
22041
22511
|
let image = pid;
|
|
22042
22512
|
for (; ; ) {
|
|
22043
|
-
const
|
|
22044
|
-
if (!
|
|
22045
|
-
image =
|
|
22513
|
+
const next3 = members.find((m) => m.execParent === image);
|
|
22514
|
+
if (!next3) return image;
|
|
22515
|
+
image = next3.pid;
|
|
22046
22516
|
}
|
|
22047
22517
|
}
|
|
22048
22518
|
credOf(pid) {
|
|
@@ -22329,7 +22799,7 @@ var Launcher = class {
|
|
|
22329
22799
|
this.pnpmStale();
|
|
22330
22800
|
if (!detach) return;
|
|
22331
22801
|
for (const nodes of this.openFiles) nodes.revoke(at);
|
|
22332
|
-
for (const
|
|
22802
|
+
for (const holds2 of this.held) holds2.revoke(at);
|
|
22333
22803
|
}
|
|
22334
22804
|
unmountAll() {
|
|
22335
22805
|
this.booting.abort();
|
|
@@ -22475,7 +22945,7 @@ var Launcher = class {
|
|
|
22475
22945
|
this.openFiles.add(nodes);
|
|
22476
22946
|
const unlinked = new UnlinkedKeeper(
|
|
22477
22947
|
fs,
|
|
22478
|
-
{ [Symbol.iterator]: () => [this.held, this.openFiles].flatMap((
|
|
22948
|
+
{ [Symbol.iterator]: () => [this.held, this.openFiles].flatMap((set3) => [...set3]).values() },
|
|
22479
22949
|
(path) => this.mountRoot(path),
|
|
22480
22950
|
{
|
|
22481
22951
|
locks: webLocks(),
|
|
@@ -22503,11 +22973,32 @@ var Launcher = class {
|
|
|
22503
22973
|
commandFs(root) {
|
|
22504
22974
|
return withCommandDirs(
|
|
22505
22975
|
root,
|
|
22506
|
-
async () =>
|
|
22976
|
+
async () => this.commandNames(await this.commands()),
|
|
22507
22977
|
(dir) => this.userCommandDir(dir),
|
|
22508
|
-
this.owners
|
|
22978
|
+
this.owners,
|
|
22979
|
+
(path) => this.entryTarget(path)
|
|
22509
22980
|
);
|
|
22510
22981
|
}
|
|
22982
|
+
named = /* @__PURE__ */ new WeakMap();
|
|
22983
|
+
commandNames(commands) {
|
|
22984
|
+
let names = this.named.get(commands);
|
|
22985
|
+
if (!names) {
|
|
22986
|
+
names = new Set(commands.keys());
|
|
22987
|
+
this.named.set(commands, names);
|
|
22988
|
+
}
|
|
22989
|
+
return names;
|
|
22990
|
+
}
|
|
22991
|
+
async entryTarget(path) {
|
|
22992
|
+
const system = COMMAND2.exec(path)?.[1];
|
|
22993
|
+
const slash = path.lastIndexOf("/");
|
|
22994
|
+
const scopes = await this.userScopes();
|
|
22995
|
+
const scope = system === void 0 ? scopes.byBin.get(path.slice(0, slash)) : "";
|
|
22996
|
+
const name2 = system ?? path.slice(slash + 1);
|
|
22997
|
+
const command = scope === void 0 ? void 0 : (await this.commands(scope)).get(name2);
|
|
22998
|
+
const owner = scope ? scopes.owners?.get(scope) : void 0;
|
|
22999
|
+
const target = command && (command.shows ?? command.script ?? command.wasm);
|
|
23000
|
+
return target === void 0 ? void 0 : { path: target, ...owner ? { owner } : {} };
|
|
23001
|
+
}
|
|
22511
23002
|
processChain(fs, nodes, unlinked) {
|
|
22512
23003
|
nodes.changed = (path) => this.changes.publish(path);
|
|
22513
23004
|
nodes.dirtied = (delta) => this.changes.dirtied(delta);
|
|
@@ -22634,11 +23125,11 @@ function ipv4Place(address) {
|
|
|
22634
23125
|
return void 0;
|
|
22635
23126
|
}
|
|
22636
23127
|
function placeOf(address) {
|
|
22637
|
-
const
|
|
22638
|
-
const kind = isIP(
|
|
22639
|
-
if (kind === 4) return ipv4Place(
|
|
23128
|
+
const plain2 = address.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
23129
|
+
const kind = isIP(plain2);
|
|
23130
|
+
if (kind === 4) return ipv4Place(plain2);
|
|
22640
23131
|
if (kind !== 6) return void 0;
|
|
22641
|
-
const words2 = hextets2(
|
|
23132
|
+
const words2 = hextets2(plain2);
|
|
22642
23133
|
const embedded2 = words2.slice(0, 5).every((w) => w === 0) && (words2[5] === 65535 || words2[5] === 0);
|
|
22643
23134
|
if (embedded2 && (words2[5] === 65535 || words2[6] !== 0)) return ipv4Place(ipv4Of(words2));
|
|
22644
23135
|
if (words2.slice(0, 7).every((w) => w === 0) && (words2[7] ?? 0) <= 1) return "loopback";
|
|
@@ -22687,10 +23178,10 @@ function connectRefusal(address, port, place) {
|
|
|
22687
23178
|
return Object.assign(new Error(why), { status: 403, code: "EACCES" });
|
|
22688
23179
|
}
|
|
22689
23180
|
async function addressesOf(host, resolve2) {
|
|
22690
|
-
const
|
|
22691
|
-
if (isIP(
|
|
22692
|
-
if (loopbackName2(
|
|
22693
|
-
return resolve2(
|
|
23181
|
+
const plain2 = host.replace(/^\[(.*)\]$/, "$1");
|
|
23182
|
+
if (isIP(plain2)) return [plain2];
|
|
23183
|
+
if (loopbackName2(plain2)) return ["127.0.0.1"];
|
|
23184
|
+
return resolve2(plain2).catch(() => []);
|
|
22694
23185
|
}
|
|
22695
23186
|
async function checkDestination(target, policy, resolve2 = resolveHost) {
|
|
22696
23187
|
const url = new URL(target);
|
|
@@ -22901,26 +23392,26 @@ var MemoryFile = class {
|
|
|
22901
23392
|
return new File(this.data.blobs, this.name, { lastModified: this.lastModified });
|
|
22902
23393
|
}
|
|
22903
23394
|
async createWritable({ keepExistingData = false } = {}) {
|
|
22904
|
-
const
|
|
23395
|
+
const next3 = keepExistingData ? new Chunks([...this.data.blobs], this.data.size) : new Chunks();
|
|
22905
23396
|
let position = 0;
|
|
22906
23397
|
const put = async (data) => {
|
|
22907
23398
|
const bytes = await bytesOf(data);
|
|
22908
|
-
await
|
|
23399
|
+
await next3.write(position, bytes);
|
|
22909
23400
|
position += bytes.length;
|
|
22910
23401
|
};
|
|
22911
23402
|
return {
|
|
22912
23403
|
write: async (data) => {
|
|
22913
23404
|
if (!isParams(data)) return put(data);
|
|
22914
|
-
if (data.type === "truncate") return
|
|
23405
|
+
if (data.type === "truncate") return next3.truncate(data.size ?? 0);
|
|
22915
23406
|
position = data.position ?? position;
|
|
22916
23407
|
if (data.type === "write") await put(data.data);
|
|
22917
23408
|
},
|
|
22918
23409
|
seek: async (at) => {
|
|
22919
23410
|
position = at;
|
|
22920
23411
|
},
|
|
22921
|
-
truncate: async (size) =>
|
|
23412
|
+
truncate: async (size) => next3.truncate(size),
|
|
22922
23413
|
close: async () => {
|
|
22923
|
-
this.data =
|
|
23414
|
+
this.data = next3;
|
|
22924
23415
|
this.lastModified = Date.now();
|
|
22925
23416
|
},
|
|
22926
23417
|
abort: async () => {
|
|
@@ -23118,12 +23609,17 @@ var RemoteTransport = class {
|
|
|
23118
23609
|
waiting = /* @__PURE__ */ new Map();
|
|
23119
23610
|
nextId = 0;
|
|
23120
23611
|
sockets = /* @__PURE__ */ new Map();
|
|
23612
|
+
uploads = /* @__PURE__ */ new Map();
|
|
23121
23613
|
failure;
|
|
23122
23614
|
constructor(port, traits) {
|
|
23123
23615
|
this.port = port;
|
|
23124
23616
|
this.traits = traits;
|
|
23125
23617
|
}
|
|
23126
23618
|
receive(reply) {
|
|
23619
|
+
if (reply.net === "body-pull") {
|
|
23620
|
+
void this.pull(reply.nid);
|
|
23621
|
+
return;
|
|
23622
|
+
}
|
|
23127
23623
|
const socket = this.sockets.get(reply.nid);
|
|
23128
23624
|
if (socket && this.toSocket(reply, socket)) return;
|
|
23129
23625
|
const waiter = this.waiting.get(reply.nid);
|
|
@@ -23142,8 +23638,35 @@ var RemoteTransport = class {
|
|
|
23142
23638
|
} else return false;
|
|
23143
23639
|
return true;
|
|
23144
23640
|
}
|
|
23641
|
+
async pull(nid) {
|
|
23642
|
+
const upload = this.uploads.get(nid);
|
|
23643
|
+
if (!upload) {
|
|
23644
|
+
this.port.postMessage({ net: "body-error", nid, message: "the request body is gone" });
|
|
23645
|
+
return;
|
|
23646
|
+
}
|
|
23647
|
+
try {
|
|
23648
|
+
const next3 = await upload.next();
|
|
23649
|
+
if (next3.done) {
|
|
23650
|
+
this.uploads.delete(nid);
|
|
23651
|
+
this.port.postMessage({ net: "body-end", nid });
|
|
23652
|
+
} else this.port.postMessage({ net: "body-chunk", nid, bytes: next3.value });
|
|
23653
|
+
} catch (e) {
|
|
23654
|
+
this.uploads.delete(nid);
|
|
23655
|
+
this.port.postMessage({
|
|
23656
|
+
net: "body-error",
|
|
23657
|
+
nid,
|
|
23658
|
+
message: e instanceof Error ? e.message : String(e)
|
|
23659
|
+
});
|
|
23660
|
+
}
|
|
23661
|
+
}
|
|
23662
|
+
dropUpload(nid) {
|
|
23663
|
+
const upload = this.uploads.get(nid);
|
|
23664
|
+
this.uploads.delete(nid);
|
|
23665
|
+
void upload?.return?.().catch(() => void 0);
|
|
23666
|
+
}
|
|
23145
23667
|
fail(error) {
|
|
23146
23668
|
this.failure = error;
|
|
23669
|
+
for (const nid of [...this.uploads.keys()]) this.dropUpload(nid);
|
|
23147
23670
|
for (const waiter of this.waiting.values()) waiter.reject(error);
|
|
23148
23671
|
this.waiting.clear();
|
|
23149
23672
|
for (const socket of this.sockets.values())
|
|
@@ -23170,14 +23693,17 @@ var RemoteTransport = class {
|
|
|
23170
23693
|
let finished = false;
|
|
23171
23694
|
const abort = () => {
|
|
23172
23695
|
finished = true;
|
|
23696
|
+
this.dropUpload(nid);
|
|
23173
23697
|
this.cancel(nid);
|
|
23174
23698
|
};
|
|
23175
23699
|
signal.addEventListener("abort", abort, { once: true });
|
|
23176
23700
|
const finish = () => {
|
|
23701
|
+
this.dropUpload(nid);
|
|
23177
23702
|
if (finished) return;
|
|
23178
23703
|
finished = true;
|
|
23179
23704
|
signal.removeEventListener("abort", abort);
|
|
23180
23705
|
};
|
|
23706
|
+
if (request.bodyStream) this.uploads.set(nid, request.bodyStream[Symbol.asyncIterator]());
|
|
23181
23707
|
let head;
|
|
23182
23708
|
try {
|
|
23183
23709
|
head = await this.ask({
|
|
@@ -23186,7 +23712,7 @@ var RemoteTransport = class {
|
|
|
23186
23712
|
url: request.url,
|
|
23187
23713
|
method: request.method,
|
|
23188
23714
|
headers: request.headers,
|
|
23189
|
-
...request.body ? { body: request.body } : {}
|
|
23715
|
+
...request.bodyStream ? { streamed: true } : request.body ? { body: request.body } : {}
|
|
23190
23716
|
});
|
|
23191
23717
|
} catch (e) {
|
|
23192
23718
|
finish();
|
|
@@ -23455,11 +23981,11 @@ function stream(chunks2, socket, signal) {
|
|
|
23455
23981
|
},
|
|
23456
23982
|
async pull(controller) {
|
|
23457
23983
|
try {
|
|
23458
|
-
const
|
|
23459
|
-
if (
|
|
23984
|
+
const next3 = await chunks2.next();
|
|
23985
|
+
if (next3.done) {
|
|
23460
23986
|
controller.close();
|
|
23461
23987
|
socket.close();
|
|
23462
|
-
} else controller.enqueue(
|
|
23988
|
+
} else controller.enqueue(next3.value);
|
|
23463
23989
|
} catch (err) {
|
|
23464
23990
|
controller.error(err);
|
|
23465
23991
|
socket.close();
|
|
@@ -23816,9 +24342,9 @@ async function terminalOn(channel, argv, opts) {
|
|
|
23816
24342
|
get onData() {
|
|
23817
24343
|
return listener;
|
|
23818
24344
|
},
|
|
23819
|
-
set onData(
|
|
23820
|
-
listener =
|
|
23821
|
-
if (
|
|
24345
|
+
set onData(next3) {
|
|
24346
|
+
listener = next3;
|
|
24347
|
+
if (next3) for (const bytes of backlog.splice(0)) next3(bytes);
|
|
23822
24348
|
},
|
|
23823
24349
|
write: (data) => send({ action: "write", bytes: bytesOf2(data) }),
|
|
23824
24350
|
resize: (cols, rows) => send({ action: "resize", cols, rows }),
|
|
@@ -23964,7 +24490,12 @@ function hostfsFetchOf(options) {
|
|
|
23964
24490
|
};
|
|
23965
24491
|
}
|
|
23966
24492
|
function nodeTransport(options = {}) {
|
|
23967
|
-
const transport = fetchTransport({
|
|
24493
|
+
const transport = fetchTransport({
|
|
24494
|
+
webSocket: true,
|
|
24495
|
+
webSocketHeaders: true,
|
|
24496
|
+
redirect: "manual",
|
|
24497
|
+
streamingBodies: true
|
|
24498
|
+
});
|
|
23968
24499
|
const open = { ...transport, traits: { ...transport.traits, crossOrigin: "any" } };
|
|
23969
24500
|
return diagnosing(guardedLoopback(open, options.hostLoopback ?? false));
|
|
23970
24501
|
}
|
|
@@ -24110,9 +24641,9 @@ async function createNodeKernel(options = {}) {
|
|
|
24110
24641
|
get onData() {
|
|
24111
24642
|
return listener;
|
|
24112
24643
|
},
|
|
24113
|
-
set onData(
|
|
24114
|
-
listener =
|
|
24115
|
-
if (
|
|
24644
|
+
set onData(next3) {
|
|
24645
|
+
listener = next3;
|
|
24646
|
+
if (next3) for (const bytes of backlog.splice(0)) next3(bytes);
|
|
24116
24647
|
},
|
|
24117
24648
|
write: (data) => session.write(typeof data === "string" ? new TextEncoder().encode(data) : data),
|
|
24118
24649
|
resize: (cols, rows) => session.resize(cols, rows),
|