@ai-ecoverse/slicc-kernel 1.171.0 → 1.172.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -7
- package/dist/driver-worker.js +4 -2
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +216 -36
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +507 -196
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +4 -2
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +455 -232
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/testing.js +498 -3
- package/dist/testing.js.map +4 -4
- package/dist/types/fs/attest.d.ts +12 -2
- package/dist/types/index.d.ts +12 -4
- package/dist/types/kernel/net/http-syscalls.d.ts +3 -1
- package/dist/types/kernel/net/loopback-transport.d.ts +1 -1
- package/dist/types/kernel/net/placeholder-floor.d.ts +9 -3
- package/dist/types/kernel/net/remote-transport.d.ts +4 -1
- package/dist/types/kernel/net/sealed-fetch.d.ts +27 -0
- package/dist/types/kernel/net/transport.d.ts +2 -1
- package/dist/types/kernel/socket.d.ts +4 -1
- package/dist/types/launcher.d.ts +12 -2
- package/dist/types/node.d.ts +12 -4
- package/dist/types/sealed-relay.d.ts +12 -2
- package/dist/types/serve.d.ts +8 -1
- package/dist/types/testing.d.ts +3 -0
- package/dist/types/transport.d.ts +2 -1
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -2362,9 +2362,9 @@ var KernelSocket = class _KernelSocket {
|
|
|
2362
2362
|
case SO_TYPE:
|
|
2363
2363
|
return SOCK_STREAM;
|
|
2364
2364
|
case SO_ERROR: {
|
|
2365
|
-
const
|
|
2365
|
+
const failed5 = this.failed;
|
|
2366
2366
|
this.failed = void 0;
|
|
2367
|
-
return
|
|
2367
|
+
return failed5 ? wasiErrno(failed5) : 0;
|
|
2368
2368
|
}
|
|
2369
2369
|
case SO_ACCEPTCONN:
|
|
2370
2370
|
return this.state === "listening" ? 1 : 0;
|
|
@@ -2444,6 +2444,7 @@ var LoopbackNet = class {
|
|
|
2444
2444
|
internal = /* @__PURE__ */ new Set();
|
|
2445
2445
|
reserved = /* @__PURE__ */ new Set();
|
|
2446
2446
|
facades = /* @__PURE__ */ new Map();
|
|
2447
|
+
proxyStamped;
|
|
2447
2448
|
nextEphemeral = EPHEMERAL_FIRST;
|
|
2448
2449
|
route;
|
|
2449
2450
|
origins;
|
|
@@ -2518,9 +2519,15 @@ var LoopbackNet = class {
|
|
|
2518
2519
|
this.kernelOnly(port, true);
|
|
2519
2520
|
this.facades.set(port, name2);
|
|
2520
2521
|
}
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2522
|
+
stampProxy(port) {
|
|
2523
|
+
this.proxyStamped = port;
|
|
2524
|
+
}
|
|
2525
|
+
get originsStamped() {
|
|
2526
|
+
return this.proxyStamped !== void 0;
|
|
2527
|
+
}
|
|
2528
|
+
stampsPeers(addr) {
|
|
2529
|
+
if (addr.family !== "inet" || !isLoopback(canonicalHost(addr.host))) return false;
|
|
2530
|
+
return this.facades.has(addr.port) || this.proxyStamped === addr.port;
|
|
2524
2531
|
}
|
|
2525
2532
|
activate(addr, start2) {
|
|
2526
2533
|
this.activators.set(keyOf(addr), start2);
|
|
@@ -3695,7 +3702,7 @@ function satisfies(version, range2) {
|
|
|
3695
3702
|
}
|
|
3696
3703
|
|
|
3697
3704
|
// src/version.ts
|
|
3698
|
-
var KERNEL_VERSION = true ? "1.
|
|
3705
|
+
var KERNEL_VERSION = true ? "1.172.0" : "0.0.0-dev";
|
|
3699
3706
|
var OS_RELEASE = "6.0.0-slicc";
|
|
3700
3707
|
function procVersion() {
|
|
3701
3708
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -4352,32 +4359,32 @@ function nextFire(schedule, after, utc = false) {
|
|
|
4352
4359
|
}
|
|
4353
4360
|
return null;
|
|
4354
4361
|
}
|
|
4355
|
-
function missedFires(schedule, from,
|
|
4362
|
+
function missedFires(schedule, from, until2, utc = false, cap = MISSED_CAP) {
|
|
4356
4363
|
let count2 = 0;
|
|
4357
4364
|
let last = null;
|
|
4358
4365
|
let at = from;
|
|
4359
4366
|
while (count2 < cap) {
|
|
4360
4367
|
at = nextFire(schedule, at, utc);
|
|
4361
|
-
if (at === null || at >
|
|
4368
|
+
if (at === null || at > until2) return { count: count2, last, more: false };
|
|
4362
4369
|
last = at;
|
|
4363
4370
|
count2++;
|
|
4364
4371
|
}
|
|
4365
4372
|
const next3 = nextFire(schedule, last, utc);
|
|
4366
|
-
if (next3 === null || next3 >
|
|
4367
|
-
return { count: count2, last: latestFire(schedule, last,
|
|
4373
|
+
if (next3 === null || next3 > until2) return { count: count2, last, more: false };
|
|
4374
|
+
return { count: count2, last: latestFire(schedule, last, until2, utc), more: true };
|
|
4368
4375
|
}
|
|
4369
|
-
function latestFire(schedule, from,
|
|
4376
|
+
function latestFire(schedule, from, until2, utc = false) {
|
|
4370
4377
|
let found = from;
|
|
4371
4378
|
for (let span = 6e4; ; span *= 2) {
|
|
4372
|
-
const start2 = Math.max(from,
|
|
4379
|
+
const start2 = Math.max(from, until2 - span);
|
|
4373
4380
|
const first = nextFire(schedule, start2, utc);
|
|
4374
|
-
if (first !== null && first <=
|
|
4381
|
+
if (first !== null && first <= until2) {
|
|
4375
4382
|
found = first;
|
|
4376
4383
|
break;
|
|
4377
4384
|
}
|
|
4378
4385
|
if (start2 === from) return from;
|
|
4379
4386
|
}
|
|
4380
|
-
for (let at = nextFire(schedule, found, utc); at !== null && at <=
|
|
4387
|
+
for (let at = nextFire(schedule, found, utc); at !== null && at <= until2; ) {
|
|
4381
4388
|
found = at;
|
|
4382
4389
|
at = nextFire(schedule, at, utc);
|
|
4383
4390
|
}
|
|
@@ -5102,12 +5109,12 @@ var UnlinkedKeeper = class {
|
|
|
5102
5109
|
return this.locks;
|
|
5103
5110
|
}
|
|
5104
5111
|
async undoing(op, peers, sends, heard, shared2 = []) {
|
|
5105
|
-
let
|
|
5112
|
+
let failed5;
|
|
5106
5113
|
let out;
|
|
5107
5114
|
try {
|
|
5108
5115
|
out = await op();
|
|
5109
5116
|
} catch (err) {
|
|
5110
|
-
|
|
5117
|
+
failed5 = err ?? new Error("failed");
|
|
5111
5118
|
await this.rollBackAsides(sends, shared2);
|
|
5112
5119
|
}
|
|
5113
5120
|
const hiddenShared = new Set(shared2.map((one) => one.hidden));
|
|
@@ -5128,7 +5135,7 @@ var UnlinkedKeeper = class {
|
|
|
5128
5135
|
const done4 = () => one.release().then(() => this.dropIfLast(one.hidden));
|
|
5129
5136
|
void Promise.all(waits.map(({ told }) => told)).then(done4, done4);
|
|
5130
5137
|
}
|
|
5131
|
-
if (
|
|
5138
|
+
if (failed5 !== void 0) throw failed5;
|
|
5132
5139
|
return out;
|
|
5133
5140
|
}
|
|
5134
5141
|
async rollBackAsides(sends, shared2) {
|
|
@@ -5275,7 +5282,7 @@ var UnlinkedKeeper = class {
|
|
|
5275
5282
|
// src/cron/clock.ts
|
|
5276
5283
|
var systemCronClock = {
|
|
5277
5284
|
now: () => Date.now(),
|
|
5278
|
-
sleep(
|
|
5285
|
+
sleep(until2, signal) {
|
|
5279
5286
|
if (signal.aborted) return Promise.resolve();
|
|
5280
5287
|
return new Promise((resolve2) => {
|
|
5281
5288
|
const done4 = () => {
|
|
@@ -5283,7 +5290,7 @@ var systemCronClock = {
|
|
|
5283
5290
|
signal.removeEventListener("abort", done4);
|
|
5284
5291
|
resolve2();
|
|
5285
5292
|
};
|
|
5286
|
-
const timer = setTimeout(done4, Math.max(0,
|
|
5293
|
+
const timer = setTimeout(done4, Math.max(0, until2 - Date.now()));
|
|
5287
5294
|
timer.unref?.();
|
|
5288
5295
|
signal.addEventListener("abort", done4, { once: true });
|
|
5289
5296
|
});
|
|
@@ -5387,15 +5394,15 @@ var CronService = class {
|
|
|
5387
5394
|
async pass() {
|
|
5388
5395
|
if (this.wake.signal.aborted) this.wake = new AbortController();
|
|
5389
5396
|
const wake = this.wake;
|
|
5390
|
-
let
|
|
5397
|
+
let until2;
|
|
5391
5398
|
try {
|
|
5392
|
-
|
|
5399
|
+
until2 = await this.tick();
|
|
5393
5400
|
} catch (err) {
|
|
5394
5401
|
await this.error(`cron: ${messageOf(err)}`);
|
|
5395
|
-
|
|
5402
|
+
until2 = this.clock.now() + WAKE_MS;
|
|
5396
5403
|
}
|
|
5397
5404
|
if (this.stopping.signal.aborted) return;
|
|
5398
|
-
await this.clock.sleep(
|
|
5405
|
+
await this.clock.sleep(until2, wake.signal);
|
|
5399
5406
|
}
|
|
5400
5407
|
async provision() {
|
|
5401
5408
|
const { fs, owners } = this.host;
|
|
@@ -5612,14 +5619,17 @@ var PLACEHOLDER_REFUSED = "refused: this request has a sealed placeholder in its
|
|
|
5612
5619
|
var PlaceholderRefused = class extends Error {
|
|
5613
5620
|
status = 403;
|
|
5614
5621
|
code = "EACCES";
|
|
5615
|
-
constructor() {
|
|
5616
|
-
super(
|
|
5622
|
+
constructor(reason = PLACEHOLDER_REFUSED) {
|
|
5623
|
+
super(reason);
|
|
5617
5624
|
}
|
|
5618
5625
|
};
|
|
5619
|
-
function
|
|
5626
|
+
function holds2(text, known) {
|
|
5627
|
+
return PLACEHOLDER.test(text) || known.some((placeholder) => text.includes(placeholder));
|
|
5628
|
+
}
|
|
5629
|
+
function carries(text, known) {
|
|
5620
5630
|
let layer = text;
|
|
5621
5631
|
for (let i = 0; i < PERCENT_LAYERS; i++) {
|
|
5622
|
-
if (
|
|
5632
|
+
if (holds2(layer, known)) return true;
|
|
5623
5633
|
const next3 = layer.replace(
|
|
5624
5634
|
ESCAPE,
|
|
5625
5635
|
(_, hex4) => String.fromCharCode(Number.parseInt(hex4, 16))
|
|
@@ -5627,35 +5637,36 @@ function carries(text) {
|
|
|
5627
5637
|
if (next3 === layer) return false;
|
|
5628
5638
|
layer = next3;
|
|
5629
5639
|
}
|
|
5630
|
-
return
|
|
5640
|
+
return holds2(layer, known);
|
|
5631
5641
|
}
|
|
5632
|
-
function basicCarries(value2) {
|
|
5642
|
+
function basicCarries(value2, known) {
|
|
5633
5643
|
const credential = BASIC.exec(value2)?.[1];
|
|
5634
5644
|
if (credential === void 0) return false;
|
|
5635
5645
|
const letters = credential.replace(/[^A-Za-z0-9+/_-]/g, "").replaceAll("-", "+").replaceAll("_", "/");
|
|
5636
5646
|
for (let shift = 0; shift < BASE64_GROUP; shift++) {
|
|
5637
5647
|
const part = letters.slice(shift);
|
|
5638
5648
|
const whole = part.length % BASE64_GROUP === 1 ? part.slice(0, -1) : part;
|
|
5639
|
-
if (carries(atob(whole))) return true;
|
|
5649
|
+
if (carries(atob(whole), known)) return true;
|
|
5640
5650
|
}
|
|
5641
5651
|
return false;
|
|
5642
5652
|
}
|
|
5643
|
-
function headersCarry(headers) {
|
|
5653
|
+
function headersCarry(headers, known) {
|
|
5644
5654
|
return headers.some(
|
|
5645
|
-
([name2, value2]) => carries(name2.toLowerCase()) || carries(value2) || basicCarries(value2)
|
|
5655
|
+
([name2, value2]) => carries(name2, known) || carries(name2.toLowerCase(), known) || carries(value2, known) || basicCarries(value2, known)
|
|
5646
5656
|
);
|
|
5647
5657
|
}
|
|
5648
|
-
function urlCarries(url) {
|
|
5649
|
-
return carries(url) || URL.canParse(url) && carries(new URL(url).href);
|
|
5658
|
+
function urlCarries(url, known) {
|
|
5659
|
+
return carries(url, known) || URL.canParse(url) && carries(new URL(url).href, known);
|
|
5650
5660
|
}
|
|
5651
|
-
function
|
|
5652
|
-
|
|
5661
|
+
function detected(request, known) {
|
|
5662
|
+
return urlCarries(request.url, known) || headersCarry(request.headers, known);
|
|
5653
5663
|
}
|
|
5654
|
-
function refuseSocket(request) {
|
|
5655
|
-
|
|
5656
|
-
|
|
5664
|
+
function refuseSocket(request, known) {
|
|
5665
|
+
if (detected(request, known) || request.protocols.some((p) => carries(p, known))) {
|
|
5666
|
+
throw new PlaceholderRefused();
|
|
5667
|
+
}
|
|
5657
5668
|
}
|
|
5658
|
-
function placeholderFloor(inner) {
|
|
5669
|
+
function placeholderFloor(inner, { known = () => [], fill: fill2 } = {}) {
|
|
5659
5670
|
const open = inner.websocket?.bind(inner);
|
|
5660
5671
|
return {
|
|
5661
5672
|
get traits() {
|
|
@@ -5663,13 +5674,14 @@ function placeholderFloor(inner) {
|
|
|
5663
5674
|
},
|
|
5664
5675
|
...open ? {
|
|
5665
5676
|
websocket: async (request) => {
|
|
5666
|
-
refuseSocket(request);
|
|
5677
|
+
refuseSocket(request, known());
|
|
5667
5678
|
return open(request);
|
|
5668
5679
|
}
|
|
5669
5680
|
} : {},
|
|
5670
|
-
async fetch(request, owner) {
|
|
5671
|
-
|
|
5672
|
-
|
|
5681
|
+
async fetch(request, owner, stamp) {
|
|
5682
|
+
if (!detected(request, known())) return inner.fetch(request, owner, stamp);
|
|
5683
|
+
if (!fill2 || !stamp) throw new PlaceholderRefused();
|
|
5684
|
+
return fill2(request, stamp);
|
|
5673
5685
|
}
|
|
5674
5686
|
};
|
|
5675
5687
|
}
|
|
@@ -5910,14 +5922,14 @@ function tunnelTarget(req) {
|
|
|
5910
5922
|
}
|
|
5911
5923
|
return { host, port };
|
|
5912
5924
|
}
|
|
5913
|
-
async function watchHangup(conn, abort,
|
|
5914
|
-
while (!
|
|
5925
|
+
async function watchHangup(conn, abort, until2) {
|
|
5926
|
+
while (!until2.aborted && !abort.signal.aborted) {
|
|
5915
5927
|
if (conn.poll().hangup) {
|
|
5916
5928
|
abort.abort(new KernelError("EPIPE"));
|
|
5917
5929
|
return;
|
|
5918
5930
|
}
|
|
5919
5931
|
try {
|
|
5920
|
-
await conn.changed(
|
|
5932
|
+
await conn.changed(until2);
|
|
5921
5933
|
} catch {
|
|
5922
5934
|
return;
|
|
5923
5935
|
}
|
|
@@ -6108,7 +6120,7 @@ var RealmProxy = class {
|
|
|
6108
6120
|
const waiting = new AbortController();
|
|
6109
6121
|
void watchHangup(ctx.socket, abort, waiting.signal);
|
|
6110
6122
|
try {
|
|
6111
|
-
response = await this.upstream(req, url, body, abort.signal, ctx.socket
|
|
6123
|
+
response = await this.upstream(req, url, body, abort.signal, ctx.socket);
|
|
6112
6124
|
} finally {
|
|
6113
6125
|
waiting.abort();
|
|
6114
6126
|
}
|
|
@@ -6135,7 +6147,7 @@ var RealmProxy = class {
|
|
|
6135
6147
|
await conn.write(latin1Bytes("HTTP/1.1 100 Continue\r\n\r\n"), this.stop.signal);
|
|
6136
6148
|
}
|
|
6137
6149
|
}
|
|
6138
|
-
async upstream(req, url, body, signal,
|
|
6150
|
+
async upstream(req, url, body, signal, socket) {
|
|
6139
6151
|
const sent = BODILESS_METHODS.has(req.method) ? void 0 : body;
|
|
6140
6152
|
try {
|
|
6141
6153
|
const fetching = this.options.transport.fetch(
|
|
@@ -6146,7 +6158,8 @@ var RealmProxy = class {
|
|
|
6146
6158
|
...sent instanceof Uint8Array ? { body: sent } : sent ? { bodyStream: sent } : {},
|
|
6147
6159
|
signal
|
|
6148
6160
|
},
|
|
6149
|
-
|
|
6161
|
+
socket.peerCred?.pid,
|
|
6162
|
+
socket.peerStamp
|
|
6150
6163
|
);
|
|
6151
6164
|
return await untilAborted(fetching, signal);
|
|
6152
6165
|
} catch (e) {
|
|
@@ -6463,7 +6476,7 @@ async function relay(socket, conn) {
|
|
|
6463
6476
|
// src/fs/attest.ts
|
|
6464
6477
|
var ATTEST_MAX = 1024 * 1024;
|
|
6465
6478
|
var UNOWNED = 1e3;
|
|
6466
|
-
function
|
|
6479
|
+
function refuse(code, path, why) {
|
|
6467
6480
|
throw Object.assign(new Error(`attest ${path}: ${why}`), { code });
|
|
6468
6481
|
}
|
|
6469
6482
|
function chainOf(path) {
|
|
@@ -6505,39 +6518,49 @@ async function trustedParents(fs, path, o) {
|
|
|
6505
6518
|
const parents = [];
|
|
6506
6519
|
for (const dir of chainOf(path).slice(0, -1)) {
|
|
6507
6520
|
const st = await fs.lstat(dir);
|
|
6508
|
-
if (st.isSymbolicLink)
|
|
6509
|
-
if (!st.isDirectory)
|
|
6521
|
+
if (st.isSymbolicLink) refuse("EACCES", path, `${dir} is a symlink`);
|
|
6522
|
+
if (!st.isDirectory) refuse("ENOTDIR", path, `${dir} is not a directory`);
|
|
6510
6523
|
const perm = owned(dir, st);
|
|
6511
6524
|
if (o.users !== "off" && (perm.uid !== 0 || (perm.mode & 18) !== 0)) {
|
|
6512
|
-
|
|
6525
|
+
refuse("EACCES", path, `${dir} is not root-owned or is writable by group or others`);
|
|
6513
6526
|
}
|
|
6514
6527
|
parents.push(perm);
|
|
6515
6528
|
}
|
|
6516
6529
|
return parents;
|
|
6517
6530
|
}
|
|
6531
|
+
function missing(e) {
|
|
6532
|
+
return e?.code === "ENOENT";
|
|
6533
|
+
}
|
|
6518
6534
|
async function attest(fs, asked, o) {
|
|
6535
|
+
if (o.absent !== void 0 && o.absent !== "allow") {
|
|
6536
|
+
refuse("EINVAL", String(asked), "absent takes only allow");
|
|
6537
|
+
}
|
|
6519
6538
|
if (typeof asked !== "string" || !asked.startsWith("/")) {
|
|
6520
|
-
|
|
6539
|
+
refuse("EINVAL", String(asked), "not an absolute path");
|
|
6521
6540
|
}
|
|
6522
6541
|
const path = normalizePath(asked);
|
|
6523
6542
|
const mount = o.mounts.find((target) => {
|
|
6524
6543
|
const at = normalizePath(target);
|
|
6525
6544
|
return at === "/" || under(path, at);
|
|
6526
6545
|
});
|
|
6527
|
-
if (mount !== void 0)
|
|
6546
|
+
if (mount !== void 0) refuse("EACCES", path, `under the mount ${mount}`);
|
|
6528
6547
|
const parents = await trustedParents(fs, path, o);
|
|
6529
6548
|
for (let tries = 0; ; tries++) {
|
|
6530
|
-
const before = await fs.lstat(path)
|
|
6531
|
-
|
|
6549
|
+
const before = await fs.lstat(path).catch((e) => {
|
|
6550
|
+
if (o.absent === "allow" && missing(e)) return void 0;
|
|
6551
|
+
throw e;
|
|
6552
|
+
});
|
|
6553
|
+
if (!before) return { path, absent: true, users: o.users, onRootFs: true, parents };
|
|
6554
|
+
if (before.isSymbolicLink) refuse("EACCES", path, "is a symlink");
|
|
6532
6555
|
if (!before.isFile)
|
|
6533
|
-
|
|
6534
|
-
if (before.size > ATTEST_MAX)
|
|
6556
|
+
refuse(before.isDirectory ? "EISDIR" : "EINVAL", path, "is not a regular file");
|
|
6557
|
+
if (before.size > ATTEST_MAX) refuse("EFBIG", path, `is over ${ATTEST_MAX} bytes`);
|
|
6535
6558
|
const bytes = (await fs.readFileBuffer(path)).slice();
|
|
6536
6559
|
const after = await fs.lstat(path);
|
|
6537
6560
|
if (unchanged(before, after, bytes)) {
|
|
6538
6561
|
return attested(path, after, bytes, await sha256(bytes), o, parents);
|
|
6539
6562
|
}
|
|
6540
|
-
if (tries >= 1)
|
|
6563
|
+
if (tries >= 1) refuse("EAGAIN", path, "changed while it was read");
|
|
6541
6564
|
}
|
|
6542
6565
|
}
|
|
6543
6566
|
var WATCH_DEBOUNCE_MS = 50;
|
|
@@ -6708,7 +6731,7 @@ var S_IFREG = 32768;
|
|
|
6708
6731
|
var COMMAND = /^\/(?:usr\/)?bin\/([^/]+)$/;
|
|
6709
6732
|
var MAX_LINKS3 = 40;
|
|
6710
6733
|
var BIN_ENTRY = /\/bin\/[^/]+$/;
|
|
6711
|
-
function
|
|
6734
|
+
function missing2(err) {
|
|
6712
6735
|
return err?.code === "ENOENT";
|
|
6713
6736
|
}
|
|
6714
6737
|
function synthetic(directory, path) {
|
|
@@ -6812,7 +6835,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
6812
6835
|
}
|
|
6813
6836
|
async function entryTarget(path) {
|
|
6814
6837
|
if (!BIN_ENTRY.test(path) || !(await virtual(path))?.isFile) return void 0;
|
|
6815
|
-
if (!await fs.lstat(path).then(() => false,
|
|
6838
|
+
if (!await fs.lstat(path).then(() => false, missing2)) return void 0;
|
|
6816
6839
|
const target = await targetOf2(path);
|
|
6817
6840
|
return target?.path === path ? void 0 : target;
|
|
6818
6841
|
}
|
|
@@ -6824,11 +6847,11 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
6824
6847
|
return target?.path;
|
|
6825
6848
|
}
|
|
6826
6849
|
const absent2 = (err) => {
|
|
6827
|
-
if (
|
|
6850
|
+
if (missing2(err)) return EMPTY2;
|
|
6828
6851
|
throw err;
|
|
6829
6852
|
};
|
|
6830
6853
|
async function content(path, err) {
|
|
6831
|
-
if (!
|
|
6854
|
+
if (!missing2(err) || !(await linked2(path))?.isFile) throw err;
|
|
6832
6855
|
const target = await redirected2(path);
|
|
6833
6856
|
return target === void 0 ? EMPTY2 : fs.readFileBuffer(target).catch(absent2);
|
|
6834
6857
|
}
|
|
@@ -6837,7 +6860,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
6837
6860
|
try {
|
|
6838
6861
|
return await real(path);
|
|
6839
6862
|
} catch (err) {
|
|
6840
|
-
const found =
|
|
6863
|
+
const found = missing2(err) ? await linked2(path) : void 0;
|
|
6841
6864
|
if (found) return found;
|
|
6842
6865
|
throw err;
|
|
6843
6866
|
}
|
|
@@ -6862,7 +6885,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
6862
6885
|
const extra = await children3(path);
|
|
6863
6886
|
if (!extra) return fs.readdir(path);
|
|
6864
6887
|
const real = await fs.readdir(path).catch((err) => {
|
|
6865
|
-
if (
|
|
6888
|
+
if (missing2(err)) return [];
|
|
6866
6889
|
throw err;
|
|
6867
6890
|
});
|
|
6868
6891
|
return [.../* @__PURE__ */ new Set([...real, ...extra])].sort();
|
|
@@ -6871,7 +6894,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
6871
6894
|
const extra = await children3(path);
|
|
6872
6895
|
if (!extra) return fs.readdirStat(path);
|
|
6873
6896
|
const real = await fs.readdirStat(path).catch((err) => {
|
|
6874
|
-
if (
|
|
6897
|
+
if (missing2(err)) return [];
|
|
6875
6898
|
throw err;
|
|
6876
6899
|
});
|
|
6877
6900
|
const seen = new Set(real.map(([name2]) => name2));
|
|
@@ -6905,7 +6928,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
|
|
|
6905
6928
|
...ranged2 ? {
|
|
6906
6929
|
...ranged2,
|
|
6907
6930
|
pread: (path, offset, length2, version) => ranged2.pread(path, offset, length2, version).catch(async (err) => {
|
|
6908
|
-
const target =
|
|
6931
|
+
const target = missing2(err) ? await redirected2(path) : void 0;
|
|
6909
6932
|
if (target === void 0) throw err;
|
|
6910
6933
|
return ranged2.pread(target, offset, length2).catch(absent2);
|
|
6911
6934
|
})
|
|
@@ -6936,7 +6959,7 @@ var S_IFREG2 = 32768;
|
|
|
6936
6959
|
var MAX_HOPS2 = 40;
|
|
6937
6960
|
var parentOf3 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
6938
6961
|
var baseOf = (path) => path.slice(path.lastIndexOf("/") + 1);
|
|
6939
|
-
function
|
|
6962
|
+
function missing3(err) {
|
|
6940
6963
|
return err?.code === "ENOENT";
|
|
6941
6964
|
}
|
|
6942
6965
|
function statOf(path, bytes) {
|
|
@@ -6989,11 +7012,11 @@ function withEtcFiles(fs, files) {
|
|
|
6989
7012
|
const text = files.get(path)?.();
|
|
6990
7013
|
return text === void 0 ? void 0 : new TextEncoder().encode(text);
|
|
6991
7014
|
};
|
|
6992
|
-
const absent2 = (path) => fs.lstat(path).then(() => false,
|
|
7015
|
+
const absent2 = (path) => fs.lstat(path).then(() => false, missing3);
|
|
6993
7016
|
const follow2 = linkFollower(fs, files);
|
|
6994
7017
|
const listedAbsent = async (path) => files.has(path) && await absent2(path) ? bytesOf5(path) : void 0;
|
|
6995
7018
|
const fallback = (path, make) => async (err) => {
|
|
6996
|
-
const at =
|
|
7019
|
+
const at = missing3(err) ? await follow2(path) : void 0;
|
|
6997
7020
|
const bytes = at === void 0 ? void 0 : await listedAbsent(at);
|
|
6998
7021
|
if (bytes === void 0 || at === void 0) throw err;
|
|
6999
7022
|
return make(bytes, at);
|
|
@@ -7203,7 +7226,7 @@ var MAX_LINKS4 = 40;
|
|
|
7203
7226
|
function partsOf(path) {
|
|
7204
7227
|
return path.split("/").filter((p) => p !== "" && p !== ".");
|
|
7205
7228
|
}
|
|
7206
|
-
function
|
|
7229
|
+
function missing4(err) {
|
|
7207
7230
|
const code = err?.code;
|
|
7208
7231
|
return code === "ENOENT" || code === "ENOTDIR";
|
|
7209
7232
|
}
|
|
@@ -7222,7 +7245,7 @@ async function resolved(fs, path, follow2, hops = []) {
|
|
|
7222
7245
|
}
|
|
7223
7246
|
const at = `/${[...done4, part].join("/")}`;
|
|
7224
7247
|
const st = await fs.lstat(at).catch((err) => {
|
|
7225
|
-
if (
|
|
7248
|
+
if (missing4(err)) return void 0;
|
|
7226
7249
|
throw err;
|
|
7227
7250
|
});
|
|
7228
7251
|
if (!st) {
|
|
@@ -9451,29 +9474,29 @@ var HeldSet = class extends Set {
|
|
|
9451
9474
|
this.idle = idle2;
|
|
9452
9475
|
this.moved = moved2;
|
|
9453
9476
|
}
|
|
9454
|
-
add(
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
return super.add(
|
|
9477
|
+
add(holds3) {
|
|
9478
|
+
holds3.onIdle = this.idle;
|
|
9479
|
+
holds3.onMoved = this.moved;
|
|
9480
|
+
return super.add(holds3);
|
|
9458
9481
|
}
|
|
9459
9482
|
doubt(paths, over) {
|
|
9460
|
-
for (const
|
|
9461
|
-
for (const path of paths)
|
|
9462
|
-
if (over !== void 0)
|
|
9483
|
+
for (const holds3 of this) {
|
|
9484
|
+
for (const path of paths) holds3.doubt(path, true);
|
|
9485
|
+
if (over !== void 0) holds3.doubt(over);
|
|
9463
9486
|
}
|
|
9464
9487
|
}
|
|
9465
9488
|
async bindIds(id2) {
|
|
9466
|
-
for (const
|
|
9489
|
+
for (const holds3 of [...this]) await holds3.bindIds(id2);
|
|
9467
9490
|
}
|
|
9468
9491
|
heldIds() {
|
|
9469
9492
|
const out = /* @__PURE__ */ new Map();
|
|
9470
|
-
for (const
|
|
9493
|
+
for (const holds3 of this) for (const [path, fid] of holds3.heldIds()) out.set(path, fid);
|
|
9471
9494
|
return [...out];
|
|
9472
9495
|
}
|
|
9473
|
-
delete(
|
|
9474
|
-
const removed = super.delete(
|
|
9475
|
-
for (const path of /* @__PURE__ */ new Set([...
|
|
9476
|
-
|
|
9496
|
+
delete(holds3) {
|
|
9497
|
+
const removed = super.delete(holds3);
|
|
9498
|
+
for (const path of /* @__PURE__ */ new Set([...holds3.keys(), ...holds3.opens.keys()])) this.idle(path);
|
|
9499
|
+
holds3.releaseAll();
|
|
9477
9500
|
return removed;
|
|
9478
9501
|
}
|
|
9479
9502
|
};
|
|
@@ -12364,9 +12387,9 @@ var SYS_TREE = {
|
|
|
12364
12387
|
`,
|
|
12365
12388
|
slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
|
|
12366
12389
|
`,
|
|
12367
|
-
slicc_peer_holds: ({ holds:
|
|
12390
|
+
slicc_peer_holds: ({ holds: holds3 }) => `${holds3?.mine ?? 0} ${holds3?.peers ?? 0} ${holds3?.sent ?? 0}
|
|
12368
12391
|
`,
|
|
12369
|
-
slicc_peer_held: ({ holds:
|
|
12392
|
+
slicc_peer_held: ({ holds: holds3 }) => (holds3?.held ?? []).map((path) => `${path}
|
|
12370
12393
|
`).join(""),
|
|
12371
12394
|
slicc_rename_acks: (listing) => {
|
|
12372
12395
|
const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
|
|
@@ -13107,11 +13130,11 @@ var EpollFile = class _EpollFile {
|
|
|
13107
13130
|
const round = new AbortController();
|
|
13108
13131
|
const stop = () => round.abort();
|
|
13109
13132
|
signal.addEventListener("abort", stop, { once: true });
|
|
13110
|
-
let
|
|
13133
|
+
let failed5 = false;
|
|
13111
13134
|
try {
|
|
13112
13135
|
await file.changed(round.signal);
|
|
13113
13136
|
} catch {
|
|
13114
|
-
|
|
13137
|
+
failed5 = true;
|
|
13115
13138
|
} finally {
|
|
13116
13139
|
round.abort();
|
|
13117
13140
|
signal.removeEventListener("abort", stop);
|
|
@@ -13119,7 +13142,7 @@ var EpollFile = class _EpollFile {
|
|
|
13119
13142
|
if (signal.aborted) return;
|
|
13120
13143
|
reg.gen++;
|
|
13121
13144
|
this.changes.wake();
|
|
13122
|
-
if (
|
|
13145
|
+
if (failed5) await pause(RETRY_MS, signal);
|
|
13123
13146
|
}
|
|
13124
13147
|
}
|
|
13125
13148
|
};
|
|
@@ -14100,11 +14123,11 @@ function ipv6(host) {
|
|
|
14100
14123
|
const back = halves.length === 2 ? groups(halves[1]) : [];
|
|
14101
14124
|
if (![...head, ...back].every((g) => /^[0-9A-Fa-f]{1,4}$/.test(g))) return void 0;
|
|
14102
14125
|
const words2 = [...head, ...back].map((g) => Number.parseInt(g, 16));
|
|
14103
|
-
const
|
|
14104
|
-
if (halves.length === 2 ?
|
|
14126
|
+
const missing6 = 8 - words2.length - tail2.length;
|
|
14127
|
+
if (halves.length === 2 ? missing6 < 1 : missing6 !== 0) return void 0;
|
|
14105
14128
|
const all = [
|
|
14106
14129
|
...head.map((g) => Number.parseInt(g, 16)),
|
|
14107
|
-
...new Array(halves.length === 2 ?
|
|
14130
|
+
...new Array(halves.length === 2 ? missing6 : 0).fill(0),
|
|
14108
14131
|
...back.map((g) => Number.parseInt(g, 16)),
|
|
14109
14132
|
...tail2
|
|
14110
14133
|
];
|
|
@@ -15101,10 +15124,12 @@ var HttpHandles = class {
|
|
|
15101
15124
|
ws;
|
|
15102
15125
|
owner;
|
|
15103
15126
|
local;
|
|
15104
|
-
|
|
15127
|
+
stamp;
|
|
15128
|
+
constructor(transport, owner, local2, stamp) {
|
|
15105
15129
|
this.transport = transport;
|
|
15106
15130
|
this.owner = owner;
|
|
15107
15131
|
this.local = local2;
|
|
15132
|
+
this.stamp = stamp;
|
|
15108
15133
|
this.ws = new WsHandles(transport, () => ++this.nextHandle, local2);
|
|
15109
15134
|
}
|
|
15110
15135
|
syscall(req) {
|
|
@@ -15180,7 +15205,7 @@ var HttpHandles = class {
|
|
|
15180
15205
|
...entry.upload ? { bodyStream: entry.upload } : req.body ? { body: req.body } : {},
|
|
15181
15206
|
signal: entry.abort.signal
|
|
15182
15207
|
};
|
|
15183
|
-
const response = port === void 0 ? await this.transport.fetch(request, this.owner) : await this.local.fetch(request, port);
|
|
15208
|
+
const response = port === void 0 ? await this.transport.fetch(request, this.owner, await this.stamp?.()) : await this.local.fetch(request, port);
|
|
15184
15209
|
entry.body = response.body[Symbol.asyncIterator]();
|
|
15185
15210
|
entry.cancel = () => response.cancel();
|
|
15186
15211
|
if (!this.open.has(handle)) await entry.cancel().catch(() => void 0);
|
|
@@ -15202,8 +15227,8 @@ var HttpHandles = class {
|
|
|
15202
15227
|
if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
|
|
15203
15228
|
const code = codeOf2(e);
|
|
15204
15229
|
const errno3 = text === NO_TRANSPORT ? "ENETUNREACH" : code !== "EIO" ? code : "ECONNREFUSED";
|
|
15205
|
-
const
|
|
15206
|
-
return { ok: false, errno: errno3, message: text, ...
|
|
15230
|
+
const failed5 = e.detail === "transport";
|
|
15231
|
+
return { ok: false, errno: errno3, message: text, ...failed5 ? { detail: "transport" } : {} };
|
|
15207
15232
|
}
|
|
15208
15233
|
entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
|
|
15209
15234
|
return this.headOf(handle, req.url, {
|
|
@@ -16998,7 +17023,7 @@ function pass(c, input, final) {
|
|
|
16998
17023
|
const partials = [];
|
|
16999
17024
|
scanMain(c, input, best, partials);
|
|
17000
17025
|
scanWrapped(c, input, best, partials);
|
|
17001
|
-
const
|
|
17026
|
+
const holds3 = final ? [] : [...new Set(partials)].sort((a, b) => a - b);
|
|
17002
17027
|
const starts = [...best.keys()].sort((a, b) => a - b);
|
|
17003
17028
|
const parts2 = [];
|
|
17004
17029
|
const hits = /* @__PURE__ */ new Map();
|
|
@@ -17008,8 +17033,8 @@ function pass(c, input, final) {
|
|
|
17008
17033
|
let h = 0;
|
|
17009
17034
|
for (; ; ) {
|
|
17010
17035
|
while (s < starts.length && starts[s] < pos) s++;
|
|
17011
|
-
while (h <
|
|
17012
|
-
const hold = h <
|
|
17036
|
+
while (h < holds3.length && holds3[h] < pos) h++;
|
|
17037
|
+
const hold = h < holds3.length ? holds3[h] : Infinity;
|
|
17013
17038
|
const next3 = s < starts.length ? starts[s] : Infinity;
|
|
17014
17039
|
if (hold <= next3) {
|
|
17015
17040
|
cut = Math.min(hold, input.length);
|
|
@@ -17111,23 +17136,23 @@ function scrubbed(inner, scrubber, idleMs = SCRUB_IDLE_MS) {
|
|
|
17111
17136
|
let pending = 0;
|
|
17112
17137
|
let busy = false;
|
|
17113
17138
|
let timer;
|
|
17114
|
-
let
|
|
17139
|
+
let failed5;
|
|
17115
17140
|
const waiters = /* @__PURE__ */ new Set();
|
|
17116
17141
|
const quiet3 = () => !busy && pending === 0;
|
|
17117
17142
|
const wake = () => {
|
|
17118
17143
|
for (const waiter of [...waiters]) waiter();
|
|
17119
17144
|
};
|
|
17120
17145
|
const raise = () => {
|
|
17121
|
-
if (
|
|
17122
|
-
const err =
|
|
17123
|
-
|
|
17146
|
+
if (failed5 === void 0) return;
|
|
17147
|
+
const err = failed5;
|
|
17148
|
+
failed5 = void 0;
|
|
17124
17149
|
throw err;
|
|
17125
17150
|
};
|
|
17126
17151
|
const later = (bytes) => {
|
|
17127
17152
|
if (bytes.length === 0) return;
|
|
17128
17153
|
pending += 1;
|
|
17129
17154
|
tail2 = tail2.then(() => writeAll2(file, bytes)).catch((err) => {
|
|
17130
|
-
if (
|
|
17155
|
+
if (failed5 === void 0) failed5 = err;
|
|
17131
17156
|
}).finally(() => {
|
|
17132
17157
|
pending -= 1;
|
|
17133
17158
|
if (quiet3()) wake();
|
|
@@ -20202,7 +20227,7 @@ async function connect(req, proc) {
|
|
|
20202
20227
|
}
|
|
20203
20228
|
const path = filePath(req.addr);
|
|
20204
20229
|
const name2 = path !== void 0 ? await proc.names?.find(path) : void 0;
|
|
20205
|
-
const stamp = proc.net.
|
|
20230
|
+
const stamp = proc.net.stampsPeers(req.addr) && await proc.stamp?.();
|
|
20206
20231
|
const dialing = target.connect(req.addr, true, proc.cred?.(), stamp || void 0, true, name2);
|
|
20207
20232
|
if (req.nonblock) {
|
|
20208
20233
|
dialing?.catch(() => void 0);
|
|
@@ -20324,7 +20349,7 @@ async function secureConnect(req, proc) {
|
|
|
20324
20349
|
delete req.clientCert;
|
|
20325
20350
|
throw new KernelError("ENOTSUP");
|
|
20326
20351
|
}
|
|
20327
|
-
return { ...tlsOverTransport(req, proc), path: "transport", substitutes: true };
|
|
20352
|
+
return { ...await tlsOverTransport(req, proc), path: "transport", substitutes: true };
|
|
20328
20353
|
}
|
|
20329
20354
|
const socket = proc.net.socket("inet");
|
|
20330
20355
|
const fd = proc.fds.install(new OpenFile(socket), 3);
|
|
@@ -20343,7 +20368,7 @@ async function uplinked(proc, host) {
|
|
|
20343
20368
|
return false;
|
|
20344
20369
|
}
|
|
20345
20370
|
}
|
|
20346
|
-
function tlsOverTransport(req, proc) {
|
|
20371
|
+
async function tlsOverTransport(req, proc) {
|
|
20347
20372
|
if (req.ca) throw new KernelError("ENOTSUP");
|
|
20348
20373
|
if (req.alpn && req.alpn.length > 0 && !req.alpn.includes("http/1.1")) {
|
|
20349
20374
|
throw new KernelError("EPROTONOSUPPORT");
|
|
@@ -20356,7 +20381,9 @@ function tlsOverTransport(req, proc) {
|
|
|
20356
20381
|
if (isLoopbackHost(servername) || isLoopbackHost(req.host)) throw new KernelError("ENOTSUP");
|
|
20357
20382
|
const host = servername.includes(":") && !servername.startsWith("[") ? `[${servername}]` : servername;
|
|
20358
20383
|
const origin = req.port === 443 ? `https://${host}` : `https://${host}:${req.port}`;
|
|
20384
|
+
const stamp = proc.net.originsStamped ? await proc.stamp?.() : void 0;
|
|
20359
20385
|
const [mine, theirs] = KernelSocket.pair(proc.net, "inet", proc.cred?.());
|
|
20386
|
+
theirs.peerStamp = stamp;
|
|
20360
20387
|
mine.peer = { family: "inet", host: req.host, port: req.port };
|
|
20361
20388
|
try {
|
|
20362
20389
|
proc.net.serveOrigin(theirs, origin);
|
|
@@ -23515,13 +23542,13 @@ function inherited(opts) {
|
|
|
23515
23542
|
...opts.cred ? { cred: opts.cred } : {}
|
|
23516
23543
|
};
|
|
23517
23544
|
}
|
|
23518
|
-
function heldBy(process2,
|
|
23519
|
-
process2.keptPath = (path) =>
|
|
23520
|
-
process2.keptHandle = (handle) =>
|
|
23521
|
-
process2.holdsHandle = (handle) =>
|
|
23545
|
+
function heldBy(process2, holds3, replacements) {
|
|
23546
|
+
process2.keptPath = (path) => holds3.keptAt(path)?.hidden;
|
|
23547
|
+
process2.keptHandle = (handle) => holds3.keptFor(handle)?.hidden;
|
|
23548
|
+
process2.holdsHandle = (handle) => holds3.holdsHandle(handle);
|
|
23522
23549
|
if (replacements) process2.replacements = replacements;
|
|
23523
23550
|
}
|
|
23524
|
-
function holdingToken(opts,
|
|
23551
|
+
function holdingToken(opts, holds3, caller) {
|
|
23525
23552
|
return mintSyncFsToken({
|
|
23526
23553
|
...opts.owners ? caller : { umask: caller.umask },
|
|
23527
23554
|
...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
|
|
@@ -23538,16 +23565,16 @@ function holdingToken(opts, holds2, caller) {
|
|
|
23538
23565
|
...opts.fileId ? { fileId: opts.fileId } : {},
|
|
23539
23566
|
...opts.announceHold ? { announceHold: opts.announceHold } : {},
|
|
23540
23567
|
...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
|
|
23541
|
-
hold: (path, on, open, real, handle, ino, fid) =>
|
|
23542
|
-
boundIno:
|
|
23543
|
-
trust:
|
|
23544
|
-
keptFor: (handle) =>
|
|
23545
|
-
heldAt: (handle) =>
|
|
23546
|
-
unlinked: (path) =>
|
|
23547
|
-
gate: (path, op) => opts.unlinkGate &&
|
|
23548
|
-
own: (path, op) =>
|
|
23549
|
-
revoked: (path) =>
|
|
23550
|
-
renamed: (from, to) =>
|
|
23568
|
+
hold: (path, on, open, real, handle, ino, fid) => holds3.hold(path, on, open, real, handle, ino, fid),
|
|
23569
|
+
boundIno: holds3.boundIno.bind(holds3),
|
|
23570
|
+
trust: holds3.trust.bind(holds3),
|
|
23571
|
+
keptFor: (handle) => holds3.keptFor(handle),
|
|
23572
|
+
heldAt: (handle) => holds3.pathOf(handle),
|
|
23573
|
+
unlinked: (path) => holds3.keptAt(path),
|
|
23574
|
+
gate: (path, op) => opts.unlinkGate && holds3.holding(path) ? opts.unlinkGate.run(holds3.keyOf(path), op) : op(),
|
|
23575
|
+
own: (path, op) => holds3.own(path, op),
|
|
23576
|
+
revoked: (path) => holds3.isRevoked(path),
|
|
23577
|
+
renamed: (from, to) => holds3.renamed(from, to)
|
|
23551
23578
|
});
|
|
23552
23579
|
}
|
|
23553
23580
|
function linksOf(opts) {
|
|
@@ -23704,15 +23731,15 @@ function spawnWasmProcess(opts) {
|
|
|
23704
23731
|
)
|
|
23705
23732
|
);
|
|
23706
23733
|
publishStops(process2, header5);
|
|
23707
|
-
const
|
|
23708
|
-
opts.held?.add(
|
|
23709
|
-
const token = holdingToken(opts,
|
|
23734
|
+
const holds3 = new HeldPaths();
|
|
23735
|
+
opts.held?.add(holds3);
|
|
23736
|
+
const token = holdingToken(opts, holds3, {
|
|
23710
23737
|
cred: () => process2.cred,
|
|
23711
23738
|
umask: () => process2.umask,
|
|
23712
23739
|
created: created4,
|
|
23713
|
-
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (
|
|
23740
|
+
holdsKept: async (path) => path.includes(`/${UNLINKED_DIR}/`) && (holds3.keeps(path) || await process2.holds(path))
|
|
23714
23741
|
});
|
|
23715
|
-
heldBy(process2,
|
|
23742
|
+
heldBy(process2, holds3, opts.replacements);
|
|
23716
23743
|
const worker = opts.createWorker();
|
|
23717
23744
|
const dying = new Dying();
|
|
23718
23745
|
const dispatch2 = (req, block) => dying.serve(
|
|
@@ -23744,7 +23771,7 @@ function spawnWasmProcess(opts) {
|
|
|
23744
23771
|
responder.dispose();
|
|
23745
23772
|
lane?.dispose();
|
|
23746
23773
|
revokeSyncFsToken(token);
|
|
23747
|
-
opts.held?.delete(
|
|
23774
|
+
opts.held?.delete(holds3);
|
|
23748
23775
|
worker.terminate();
|
|
23749
23776
|
settleExit(process2.exit(), settle, code);
|
|
23750
23777
|
};
|
|
@@ -24310,10 +24337,10 @@ var RemoteWatch = class {
|
|
|
24310
24337
|
});
|
|
24311
24338
|
}
|
|
24312
24339
|
}
|
|
24313
|
-
heldBy({ tab, holds:
|
|
24340
|
+
heldBy({ tab, holds: holds3, seq: seq2 }) {
|
|
24314
24341
|
const from = tab;
|
|
24315
|
-
const { add, drop } =
|
|
24316
|
-
if (
|
|
24342
|
+
const { add, drop } = holds3;
|
|
24343
|
+
if (holds3?.instance !== void 0) this.instances.set(from, holds3.instance);
|
|
24317
24344
|
const held = this.peerHolds.get(from) ?? /* @__PURE__ */ new Map();
|
|
24318
24345
|
for (const path of drop) held.delete(path);
|
|
24319
24346
|
for (const [path, fid] of add) held.set(path, fid);
|
|
@@ -25365,7 +25392,7 @@ var RemoteTransport = class {
|
|
|
25365
25392
|
waiter?.reject(new TransportError("the request was cancelled"));
|
|
25366
25393
|
this.port.postMessage({ net: "cancel", nid });
|
|
25367
25394
|
}
|
|
25368
|
-
async fetch(request) {
|
|
25395
|
+
async fetch(request, owner, stamp) {
|
|
25369
25396
|
const nid = ++this.nextId;
|
|
25370
25397
|
const { signal, redirect } = request;
|
|
25371
25398
|
signal.throwIfAborted();
|
|
@@ -25395,7 +25422,9 @@ var RemoteTransport = class {
|
|
|
25395
25422
|
method: request.method,
|
|
25396
25423
|
headers: request.headers,
|
|
25397
25424
|
...request.bodyStream ? { streamed: true } : request.body ? { body: request.body } : {},
|
|
25398
|
-
...redirect !== void 0 ? { redirect } : {}
|
|
25425
|
+
...redirect !== void 0 ? { redirect } : {},
|
|
25426
|
+
...owner !== void 0 ? { owner } : {},
|
|
25427
|
+
...stamp ? { stamp } : {}
|
|
25399
25428
|
});
|
|
25400
25429
|
} catch (e) {
|
|
25401
25430
|
finish();
|
|
@@ -25586,6 +25615,173 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
25586
25615
|
};
|
|
25587
25616
|
}
|
|
25588
25617
|
|
|
25618
|
+
// src/body-idle.ts
|
|
25619
|
+
var BODY_IDLE_MS = 5 * 60 * 1e3;
|
|
25620
|
+
function idleFailure(ms) {
|
|
25621
|
+
return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {
|
|
25622
|
+
code: "ETIMEDOUT"
|
|
25623
|
+
});
|
|
25624
|
+
}
|
|
25625
|
+
async function readWithin(reader, ms) {
|
|
25626
|
+
if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();
|
|
25627
|
+
let timer;
|
|
25628
|
+
const idle2 = new Promise((_, reject) => {
|
|
25629
|
+
timer = setTimeout(() => reject(idleFailure(ms)), ms);
|
|
25630
|
+
});
|
|
25631
|
+
try {
|
|
25632
|
+
return await Promise.race([reader.read(), idle2]);
|
|
25633
|
+
} finally {
|
|
25634
|
+
clearTimeout(timer);
|
|
25635
|
+
}
|
|
25636
|
+
}
|
|
25637
|
+
|
|
25638
|
+
// src/kernel/net/sealed-fetch.ts
|
|
25639
|
+
var SEALED_FETCH_VERSION = 1;
|
|
25640
|
+
var UNSAFE_FIELD = /[\r\n\0]/;
|
|
25641
|
+
function sealedHooks(option) {
|
|
25642
|
+
if (!option) return {};
|
|
25643
|
+
if (typeof option === "function") return { request: option };
|
|
25644
|
+
const { request, fetch: fetch2 } = option;
|
|
25645
|
+
if (typeof request !== "function" || fetch2 !== void 0 && typeof fetch2 !== "function") {
|
|
25646
|
+
throw new TypeError("sealed takes a function or { request, fetch? }");
|
|
25647
|
+
}
|
|
25648
|
+
return { request, ...fetch2 ? { fetch: fetch2 } : {} };
|
|
25649
|
+
}
|
|
25650
|
+
function headerList(headers) {
|
|
25651
|
+
return Array.isArray(headers) && headers.every(
|
|
25652
|
+
(field4) => Array.isArray(field4) && field4.length === 2 && field4.every((text) => typeof text === "string" && !UNSAFE_FIELD.test(text))
|
|
25653
|
+
);
|
|
25654
|
+
}
|
|
25655
|
+
function sealedReplyValid(reply) {
|
|
25656
|
+
if (typeof reply !== "object" || reply === null) return false;
|
|
25657
|
+
const { redirects, redirected: redirected2, status, statusText, headers, url, body, cancel } = reply;
|
|
25658
|
+
return redirects === void 0 && redirected2 !== true && Number.isInteger(status) && status >= 100 && status <= 599 && typeof statusText === "string" && !UNSAFE_FIELD.test(statusText) && headerList(headers) && (url === void 0 || typeof url === "string") && typeof body?.[Symbol.asyncIterator] === "function" && typeof cancel === "function";
|
|
25659
|
+
}
|
|
25660
|
+
function dropSealedReply(reply) {
|
|
25661
|
+
const { cancel } = reply ?? {};
|
|
25662
|
+
if (typeof cancel !== "function") return;
|
|
25663
|
+
void Promise.resolve().then(() => cancel.call(reply)).catch(() => void 0);
|
|
25664
|
+
}
|
|
25665
|
+
function failed2(reason) {
|
|
25666
|
+
const text = reason instanceof Error ? reason.message : String(reason);
|
|
25667
|
+
return new PlaceholderRefused(
|
|
25668
|
+
`refused: the request with a sealed placeholder was not completed: ${text}`
|
|
25669
|
+
);
|
|
25670
|
+
}
|
|
25671
|
+
var Stall = class {
|
|
25672
|
+
idle = new AbortController();
|
|
25673
|
+
ms;
|
|
25674
|
+
timer;
|
|
25675
|
+
signal;
|
|
25676
|
+
constructor(signals, ms) {
|
|
25677
|
+
this.ms = ms;
|
|
25678
|
+
this.signal = AbortSignal.any([...signals, this.idle.signal]);
|
|
25679
|
+
}
|
|
25680
|
+
arm() {
|
|
25681
|
+
clearTimeout(this.timer);
|
|
25682
|
+
this.timer = setTimeout(() => this.idle.abort("timeout"), this.ms);
|
|
25683
|
+
this.timer.unref?.();
|
|
25684
|
+
}
|
|
25685
|
+
touch() {
|
|
25686
|
+
if (this.timer !== void 0) this.arm();
|
|
25687
|
+
}
|
|
25688
|
+
rest() {
|
|
25689
|
+
clearTimeout(this.timer);
|
|
25690
|
+
this.timer = void 0;
|
|
25691
|
+
}
|
|
25692
|
+
};
|
|
25693
|
+
async function until(work, signal) {
|
|
25694
|
+
const stopped = Promise.withResolvers();
|
|
25695
|
+
const stop = () => stopped.reject(signal.reason);
|
|
25696
|
+
if (signal.aborted) stop();
|
|
25697
|
+
else signal.addEventListener("abort", stop, { once: true });
|
|
25698
|
+
try {
|
|
25699
|
+
return await Promise.race([work, stopped.promise]);
|
|
25700
|
+
} finally {
|
|
25701
|
+
signal.removeEventListener("abort", stop);
|
|
25702
|
+
}
|
|
25703
|
+
}
|
|
25704
|
+
async function* ticking(stream2, stall) {
|
|
25705
|
+
for await (const chunk2 of stream2) {
|
|
25706
|
+
stall.touch();
|
|
25707
|
+
yield chunk2;
|
|
25708
|
+
}
|
|
25709
|
+
}
|
|
25710
|
+
function sealedRequest(request, stamp, stall) {
|
|
25711
|
+
const { method, url, headers, body, bodyStream: bodyStream2 } = request;
|
|
25712
|
+
return {
|
|
25713
|
+
v: 1,
|
|
25714
|
+
caller: structuredClone(stamp),
|
|
25715
|
+
method,
|
|
25716
|
+
url,
|
|
25717
|
+
headers: headers.map(([name2, value2]) => [name2, value2]),
|
|
25718
|
+
redirect: "manual",
|
|
25719
|
+
...bodyStream2 ? { bodyStream: ticking(bodyStream2, stall) } : body ? { body } : {}
|
|
25720
|
+
};
|
|
25721
|
+
}
|
|
25722
|
+
function guarded2(reply, stall) {
|
|
25723
|
+
let finished = false;
|
|
25724
|
+
const cancel = async () => {
|
|
25725
|
+
stall.signal.removeEventListener("abort", dropped2);
|
|
25726
|
+
stall.rest();
|
|
25727
|
+
if (finished) return;
|
|
25728
|
+
finished = true;
|
|
25729
|
+
await reply.cancel().catch(() => void 0);
|
|
25730
|
+
};
|
|
25731
|
+
const dropped2 = () => void cancel();
|
|
25732
|
+
stall.signal.addEventListener("abort", dropped2, { once: true });
|
|
25733
|
+
const source = reply.body[Symbol.asyncIterator]();
|
|
25734
|
+
const body = (async function* () {
|
|
25735
|
+
try {
|
|
25736
|
+
for (; ; ) {
|
|
25737
|
+
stall.arm();
|
|
25738
|
+
const next3 = await until(source.next(), stall.signal);
|
|
25739
|
+
stall.rest();
|
|
25740
|
+
if (next3.done) {
|
|
25741
|
+
finished = true;
|
|
25742
|
+
return;
|
|
25743
|
+
}
|
|
25744
|
+
if (!(next3.value instanceof Uint8Array)) throw failed2("a body chunk is not bytes");
|
|
25745
|
+
if (next3.value.byteLength > 0) yield next3.value;
|
|
25746
|
+
}
|
|
25747
|
+
} finally {
|
|
25748
|
+
await cancel();
|
|
25749
|
+
}
|
|
25750
|
+
})();
|
|
25751
|
+
return {
|
|
25752
|
+
...reply.url !== void 0 ? { url: reply.url } : {},
|
|
25753
|
+
status: reply.status,
|
|
25754
|
+
statusText: reply.statusText,
|
|
25755
|
+
headers: reply.headers,
|
|
25756
|
+
body,
|
|
25757
|
+
cancel
|
|
25758
|
+
};
|
|
25759
|
+
}
|
|
25760
|
+
function sealedFetcher(hook, stop, idleMs = BODY_IDLE_MS) {
|
|
25761
|
+
return async (request, stamp) => {
|
|
25762
|
+
const stall = new Stall([request.signal, stop], idleMs);
|
|
25763
|
+
const { signal } = stall;
|
|
25764
|
+
if (signal.aborted) throw failed2(signal.reason);
|
|
25765
|
+
stall.arm();
|
|
25766
|
+
const asked = Promise.resolve().then(() => {
|
|
25767
|
+
signal.throwIfAborted();
|
|
25768
|
+
return hook(sealedRequest(request, stamp, stall), { signal });
|
|
25769
|
+
});
|
|
25770
|
+
let reply;
|
|
25771
|
+
try {
|
|
25772
|
+
reply = await until(asked, signal);
|
|
25773
|
+
} catch (e) {
|
|
25774
|
+
void asked.then(dropSealedReply, () => void 0);
|
|
25775
|
+
throw failed2(e);
|
|
25776
|
+
} finally {
|
|
25777
|
+
stall.rest();
|
|
25778
|
+
}
|
|
25779
|
+
if (sealedReplyValid(reply)) return guarded2(reply, stall);
|
|
25780
|
+
dropSealedReply(reply);
|
|
25781
|
+
throw failed2("the reply is not a scrubbed response");
|
|
25782
|
+
};
|
|
25783
|
+
}
|
|
25784
|
+
|
|
25589
25785
|
// src/kernel/package-swaps.ts
|
|
25590
25786
|
var SWAP_GAP_MS = 2e3;
|
|
25591
25787
|
var STAGES = ["_tmp_", "_pacquet-stage_"];
|
|
@@ -25758,11 +25954,11 @@ var PackageLocks = class {
|
|
|
25758
25954
|
if (!locks) return Promise.resolve(() => {
|
|
25759
25955
|
});
|
|
25760
25956
|
const { promise: held, resolve: release } = Promise.withResolvers();
|
|
25761
|
-
return new Promise((granted2,
|
|
25957
|
+
return new Promise((granted2, failed5) => {
|
|
25762
25958
|
locks.request(replacingLock(this.metadata, root), { mode: "exclusive" }, () => {
|
|
25763
25959
|
granted2(() => release());
|
|
25764
25960
|
return held;
|
|
25765
|
-
}).catch(
|
|
25961
|
+
}).catch(failed5);
|
|
25766
25962
|
});
|
|
25767
25963
|
}
|
|
25768
25964
|
};
|
|
@@ -26146,11 +26342,11 @@ var META_OPS = ["get", "update", "move", "remove", "links", "under", "all"];
|
|
|
26146
26342
|
var FILE_ID_TRIES = 3;
|
|
26147
26343
|
function sidecar(meta) {
|
|
26148
26344
|
const pathOf = ([first]) => [first, "/"].flat().find((p) => typeof p === "string");
|
|
26149
|
-
const
|
|
26345
|
+
const guarded4 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
|
|
26150
26346
|
throw translate(err, pathOf(args), "sidecar", false);
|
|
26151
26347
|
});
|
|
26152
26348
|
const names2 = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
|
|
26153
|
-
const ops = Object.fromEntries(names2.map((op) => [op,
|
|
26349
|
+
const ops = Object.fromEntries(names2.map((op) => [op, guarded4(op)]));
|
|
26154
26350
|
const { updateMany } = meta;
|
|
26155
26351
|
ops.updateMany = updateMany ? (changes) => updateMany.call(meta, changes).catch((err) => {
|
|
26156
26352
|
throw translate(err, changes[0]?.path ?? "/", "sidecar", false);
|
|
@@ -26174,7 +26370,7 @@ function occupied(entry) {
|
|
|
26174
26370
|
function vacatedAt(path) {
|
|
26175
26371
|
return { path, ino: inodeOf(`${path}\0${crypto.randomUUID()}`), vacated: true };
|
|
26176
26372
|
}
|
|
26177
|
-
function
|
|
26373
|
+
function missing5(err) {
|
|
26178
26374
|
const code = err?.code;
|
|
26179
26375
|
return code === "ENOENT" || code === "ENOTDIR";
|
|
26180
26376
|
}
|
|
@@ -26417,7 +26613,7 @@ var OpfsFs = class {
|
|
|
26417
26613
|
if (there) return (await this.meta.get([found.path]))[0]?.fid ?? fid;
|
|
26418
26614
|
const gone = await this.locate(found.path, true).then(
|
|
26419
26615
|
() => false,
|
|
26420
|
-
(err) =>
|
|
26616
|
+
(err) => missing5(err)
|
|
26421
26617
|
);
|
|
26422
26618
|
if (gone) {
|
|
26423
26619
|
await this.meta.update(found.path, (now) => {
|
|
@@ -26860,7 +27056,7 @@ var OpfsFs = class {
|
|
|
26860
27056
|
try {
|
|
26861
27057
|
return await op();
|
|
26862
27058
|
} catch (err) {
|
|
26863
|
-
if (attempt >= REPLACED_ATTEMPTS || !
|
|
27059
|
+
if (attempt >= REPLACED_ATTEMPTS || !missing5(err)) throw err;
|
|
26864
27060
|
await this.replacing;
|
|
26865
27061
|
if (this.replacements === seen) throw err;
|
|
26866
27062
|
}
|
|
@@ -26872,7 +27068,7 @@ var OpfsFs = class {
|
|
|
26872
27068
|
try {
|
|
26873
27069
|
return { path: current, handle: await this.handle(current) };
|
|
26874
27070
|
} catch (err) {
|
|
26875
|
-
if (!
|
|
27071
|
+
if (!missing5(err)) throw err;
|
|
26876
27072
|
const link2 = await this.linkAlong(current);
|
|
26877
27073
|
if (!link2) throw err;
|
|
26878
27074
|
if (link2.path === current && !follow2) return { path: current, link: link2 };
|
|
@@ -27108,7 +27304,7 @@ var OpfsFs = class {
|
|
|
27108
27304
|
return this.locate(path, true).then(
|
|
27109
27305
|
() => true,
|
|
27110
27306
|
(err) => {
|
|
27111
|
-
if (
|
|
27307
|
+
if (missing5(err)) return false;
|
|
27112
27308
|
throw err;
|
|
27113
27309
|
}
|
|
27114
27310
|
);
|
|
@@ -27405,7 +27601,7 @@ var OpfsFs = class {
|
|
|
27405
27601
|
try {
|
|
27406
27602
|
return [(await this.locate(path, true)).path, true];
|
|
27407
27603
|
} catch (err) {
|
|
27408
|
-
if (!
|
|
27604
|
+
if (!missing5(err)) throw err;
|
|
27409
27605
|
}
|
|
27410
27606
|
const [entry] = await this.meta.get([path]);
|
|
27411
27607
|
const wanted = entry?.link === void 0 ? path : resolvePath(parentOf9(path), entry.link);
|
|
@@ -27497,7 +27693,7 @@ var OpfsFs = class {
|
|
|
27497
27693
|
try {
|
|
27498
27694
|
found = await this.exactly(() => this.locate(path, true));
|
|
27499
27695
|
} catch (err) {
|
|
27500
|
-
if (!
|
|
27696
|
+
if (!missing5(err)) throw err;
|
|
27501
27697
|
}
|
|
27502
27698
|
if (found) {
|
|
27503
27699
|
const directory = found.handle?.kind === "directory";
|
|
@@ -27633,7 +27829,7 @@ var OpfsFs = class {
|
|
|
27633
27829
|
const taken = await this.exactly(() => this.lstat(to)).then(
|
|
27634
27830
|
() => true,
|
|
27635
27831
|
(err) => {
|
|
27636
|
-
if (
|
|
27832
|
+
if (missing5(err)) return false;
|
|
27637
27833
|
throw err;
|
|
27638
27834
|
}
|
|
27639
27835
|
);
|
|
@@ -27665,7 +27861,7 @@ var OpfsFs = class {
|
|
|
27665
27861
|
const sourceStat = await this.describe(source);
|
|
27666
27862
|
if (sourceStat.isDirectory && within9(destination, source.path)) throw fsError("EINVAL", to);
|
|
27667
27863
|
const target = await this.exactly(() => this.locate(destination, false)).catch((err) => {
|
|
27668
|
-
if (
|
|
27864
|
+
if (missing5(err)) return null;
|
|
27669
27865
|
throw err;
|
|
27670
27866
|
});
|
|
27671
27867
|
const targetStat = target && await this.describe(target);
|
|
@@ -28256,12 +28452,12 @@ var OpfsFs = class {
|
|
|
28256
28452
|
if (!move) return false;
|
|
28257
28453
|
for (let attempt = 0; ; attempt++) {
|
|
28258
28454
|
this.others++;
|
|
28259
|
-
const
|
|
28455
|
+
const failed5 = await move.call(handle, dir, name2).then(
|
|
28260
28456
|
() => void 0,
|
|
28261
28457
|
(err) => ({ err })
|
|
28262
28458
|
);
|
|
28263
|
-
if (!
|
|
28264
|
-
const error =
|
|
28459
|
+
if (!failed5) return true;
|
|
28460
|
+
const error = failed5.err?.name;
|
|
28265
28461
|
if (handle.kind !== "file" || !LOCKED.has(error)) return false;
|
|
28266
28462
|
const delay2 = SYNC_BACKOFF_MS[attempt];
|
|
28267
28463
|
if (delay2 === void 0) throw fsError("EBUSY", name2);
|
|
@@ -28302,7 +28498,7 @@ var OpfsFs = class {
|
|
|
28302
28498
|
this.refuse(at);
|
|
28303
28499
|
if (await this.exactly(() => this.locate(at, false)).then(
|
|
28304
28500
|
() => true,
|
|
28305
|
-
(err) => !
|
|
28501
|
+
(err) => !missing5(err)
|
|
28306
28502
|
)) {
|
|
28307
28503
|
throw fsError("EEXIST", path);
|
|
28308
28504
|
}
|
|
@@ -28824,22 +29020,22 @@ async function mountFstab(lines2, mount, signal, retries = FSTAB_RETRIES, discar
|
|
|
28824
29020
|
);
|
|
28825
29021
|
}
|
|
28826
29022
|
async function mountLine({ line, spec, invalid }, mount, signal, retries, discard) {
|
|
28827
|
-
let
|
|
29023
|
+
let failed5 = invalid;
|
|
28828
29024
|
for (let attempt = 0; !invalid && attempt <= retries.length && !signal.aborted; attempt++) {
|
|
28829
29025
|
try {
|
|
28830
29026
|
const entry = await mount(spec);
|
|
28831
29027
|
if (!signal.aborted) return { line, target: spec.target, entry };
|
|
28832
29028
|
discard(entry);
|
|
28833
|
-
|
|
29029
|
+
failed5 = Object.assign(new Error("the kernel stopped"), { code: "ECANCELED" });
|
|
28834
29030
|
break;
|
|
28835
29031
|
} catch (err) {
|
|
28836
|
-
|
|
29032
|
+
failed5 = err;
|
|
28837
29033
|
if (FINAL.has(codeOf6(err)) || attempt === retries.length) break;
|
|
28838
29034
|
await wait(retries[attempt], signal);
|
|
28839
29035
|
}
|
|
28840
29036
|
}
|
|
28841
|
-
const code = codeOf6(
|
|
28842
|
-
return { line, target: spec.target, code, error: String(
|
|
29037
|
+
const code = codeOf6(failed5);
|
|
29038
|
+
return { line, target: spec.target, code, error: String(failed5?.message ?? code) };
|
|
28843
29039
|
}
|
|
28844
29040
|
|
|
28845
29041
|
// src/mount/hostfs.ts
|
|
@@ -30441,7 +30637,7 @@ var RULE = new RegExp(
|
|
|
30441
30637
|
var TERM = /^[A-Za-z0-9._+-]+$/;
|
|
30442
30638
|
var PLAIN3 = /^[A-Za-z0-9_@%+=:,./-]+$/;
|
|
30443
30639
|
var USAGE = "usage: sudo [-n] [-u user] [--] command [args...]\n sudo -l";
|
|
30444
|
-
function
|
|
30640
|
+
function failed3(errno3, error) {
|
|
30445
30641
|
return { error, errno: errno3 };
|
|
30446
30642
|
}
|
|
30447
30643
|
function unescaped(double) {
|
|
@@ -30620,10 +30816,10 @@ var Sudo = class {
|
|
|
30620
30816
|
}
|
|
30621
30817
|
async untrusted(path, cwd, word) {
|
|
30622
30818
|
const files = this.o.backing ? await this.o.backing(path, cwd) : [];
|
|
30623
|
-
if (!files) return
|
|
30819
|
+
if (!files) return failed3("ENOENT", `sudo: ${word}: command not found`);
|
|
30624
30820
|
for (const file of [path, ...files]) {
|
|
30625
30821
|
if (!await this.trusted(file)) {
|
|
30626
|
-
return
|
|
30822
|
+
return failed3("EPERM", `sudo: ${file} must be root's, and writable by root only`);
|
|
30627
30823
|
}
|
|
30628
30824
|
}
|
|
30629
30825
|
return void 0;
|
|
@@ -30640,7 +30836,7 @@ var Sudo = class {
|
|
|
30640
30836
|
}
|
|
30641
30837
|
async request(caller, call, signal) {
|
|
30642
30838
|
const parsed2 = parseArgs(call.args);
|
|
30643
|
-
if (typeof parsed2 === "string") return
|
|
30839
|
+
if (typeof parsed2 === "string") return failed3("EINVAL", parsed2);
|
|
30644
30840
|
if (this.o.mode !== "enforce") {
|
|
30645
30841
|
const mode = this.o.mode;
|
|
30646
30842
|
if (parsed2.list) return { list: `sudo: users are '${mode}': commands run as the caller
|
|
@@ -30649,9 +30845,9 @@ var Sudo = class {
|
|
|
30649
30845
|
}
|
|
30650
30846
|
const { cred } = caller;
|
|
30651
30847
|
const self = await this.o.users.lookup(cred.ruid);
|
|
30652
|
-
if (!self) return
|
|
30848
|
+
if (!self) return failed3("EPERM", `sudo: uid ${cred.ruid} is not in the passwd database`);
|
|
30653
30849
|
const target = await this.lookup(parsed2.user);
|
|
30654
|
-
if (!target) return
|
|
30850
|
+
if (!target) return failed3("ENOENT", `sudo: unknown user ${parsed2.user}`);
|
|
30655
30851
|
const root = cred.euid === 0;
|
|
30656
30852
|
const rules = root ? [] : await this.policy();
|
|
30657
30853
|
const applies = await this.applies(self, cred);
|
|
@@ -30659,13 +30855,13 @@ var Sudo = class {
|
|
|
30659
30855
|
const [word = "", ...args] = parsed2.command;
|
|
30660
30856
|
const cwd = await this.canonical(call.cwd);
|
|
30661
30857
|
if (cwd === void 0 || !await this.reachable(cred, cwd)) {
|
|
30662
|
-
return
|
|
30858
|
+
return failed3(
|
|
30663
30859
|
"EACCES",
|
|
30664
30860
|
`sudo: cannot run in ${call.cwd}: it isn't a directory you can enter`
|
|
30665
30861
|
);
|
|
30666
30862
|
}
|
|
30667
30863
|
const path = await this.locate(word, cwd);
|
|
30668
|
-
if (!path) return
|
|
30864
|
+
if (!path) return failed3("ENOENT", `sudo: ${word}: command not found`);
|
|
30669
30865
|
const untrusted2 = await this.untrusted(path, cwd, word);
|
|
30670
30866
|
if (untrusted2) return untrusted2;
|
|
30671
30867
|
const argv = [path, ...args];
|
|
@@ -30676,24 +30872,24 @@ var Sudo = class {
|
|
|
30676
30872
|
if (root || matching.some((rule) => rule.nopasswd)) return grant();
|
|
30677
30873
|
const quoted = argv.map(quoteWord).join(" ");
|
|
30678
30874
|
if (matching.length === 0) {
|
|
30679
|
-
return
|
|
30875
|
+
return failed3(
|
|
30680
30876
|
"EPERM",
|
|
30681
30877
|
`sudo: ${self.name} is not allowed to run ${quoted} as ${target.name}`
|
|
30682
30878
|
);
|
|
30683
30879
|
}
|
|
30684
|
-
if (parsed2.nonInteractive) return
|
|
30685
|
-
if (this.pending.has(cred.ruid)) return
|
|
30880
|
+
if (parsed2.nonInteractive) return failed3("EPERM", "sudo: a password is required");
|
|
30881
|
+
if (this.pending.has(cred.ruid)) return failed3("EBUSY", "sudo: another request is pending");
|
|
30686
30882
|
this.pending.add(cred.ruid);
|
|
30687
30883
|
try {
|
|
30688
30884
|
const answer2 = await this.ask(caller, self, target, parsed2.command, path, cwd, signal);
|
|
30689
30885
|
if (typeof answer2 !== "string") return answer2;
|
|
30690
30886
|
if (await this.canonical(call.cwd) !== cwd || !await this.reachable(cred, cwd)) {
|
|
30691
|
-
return
|
|
30887
|
+
return failed3("EACCES", `sudo: ${call.cwd} changed while the request waited`);
|
|
30692
30888
|
}
|
|
30693
30889
|
const changed = await this.untrusted(path, cwd, word);
|
|
30694
30890
|
if (changed) return changed;
|
|
30695
30891
|
if (answer2 === "always" && !await this.remember(self, target, cwd, argv)) {
|
|
30696
|
-
return
|
|
30892
|
+
return failed3("EIO", "sudo: the rule could not be recorded");
|
|
30697
30893
|
}
|
|
30698
30894
|
return grant();
|
|
30699
30895
|
} finally {
|
|
@@ -30710,7 +30906,7 @@ var Sudo = class {
|
|
|
30710
30906
|
};
|
|
30711
30907
|
}
|
|
30712
30908
|
if (rules.length === 0) {
|
|
30713
|
-
return
|
|
30909
|
+
return failed3("EPERM", `User ${self.name} is not allowed to run sudo on ${host}.`);
|
|
30714
30910
|
}
|
|
30715
30911
|
const lines2 = rules.map(described).join("\n");
|
|
30716
30912
|
return { list: `User ${self.name} may run the following commands on ${host}:
|
|
@@ -30719,7 +30915,7 @@ ${lines2}
|
|
|
30719
30915
|
}
|
|
30720
30916
|
async ask(caller, self, target, argv, path, cwd, requester) {
|
|
30721
30917
|
const { approve } = this.o;
|
|
30722
|
-
if (!approve || requester.aborted) return
|
|
30918
|
+
if (!approve || requester.aborted) return failed3("EACCES", "sudo: approval denied");
|
|
30723
30919
|
const createdAt = Date.now();
|
|
30724
30920
|
const timeout = this.o.timeoutMs ?? SUDO_TIMEOUT_MS;
|
|
30725
30921
|
const req = {
|
|
@@ -30749,9 +30945,9 @@ ${lines2}
|
|
|
30749
30945
|
const answered = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
|
|
30750
30946
|
const answer2 = await Promise.race([answered, aborted3]);
|
|
30751
30947
|
if (answer2 === "aborted" || control.signal.aborted) {
|
|
30752
|
-
return control.signal.reason === "expired" ?
|
|
30948
|
+
return control.signal.reason === "expired" ? failed3("ETIMEDOUT", "sudo: the request expired") : failed3("EINTR", "sudo: the request was withdrawn");
|
|
30753
30949
|
}
|
|
30754
|
-
return answer2 === "once" || answer2 === "always" ? answer2 :
|
|
30950
|
+
return answer2 === "once" || answer2 === "always" ? answer2 : failed3("EACCES", "sudo: approval denied");
|
|
30755
30951
|
} finally {
|
|
30756
30952
|
clearTimeout(timer);
|
|
30757
30953
|
requester.removeEventListener("abort", withdraw);
|
|
@@ -31038,13 +31234,13 @@ function interpreter(head) {
|
|
|
31038
31234
|
function expandDefaults(defaults2, env) {
|
|
31039
31235
|
const out = {};
|
|
31040
31236
|
for (const [key, value2] of Object.entries(defaults2 ?? {})) {
|
|
31041
|
-
let
|
|
31237
|
+
let missing6 = false;
|
|
31042
31238
|
const expanded = value2.replace(ENV_REFERENCE, (_, name2) => {
|
|
31043
31239
|
const set3 = Object.hasOwn(env, name2) ? env[name2] : void 0;
|
|
31044
|
-
if (set3 === void 0)
|
|
31240
|
+
if (set3 === void 0) missing6 = true;
|
|
31045
31241
|
return set3 ?? "";
|
|
31046
31242
|
});
|
|
31047
|
-
if (!
|
|
31243
|
+
if (!missing6) out[key] = expanded;
|
|
31048
31244
|
}
|
|
31049
31245
|
return out;
|
|
31050
31246
|
}
|
|
@@ -31219,6 +31415,9 @@ var Launcher = class {
|
|
|
31219
31415
|
usersMode;
|
|
31220
31416
|
dac;
|
|
31221
31417
|
sealed;
|
|
31418
|
+
fill;
|
|
31419
|
+
fills = new AbortController();
|
|
31420
|
+
placeholders = [];
|
|
31222
31421
|
scrubs = /* @__PURE__ */ new Map();
|
|
31223
31422
|
clipboard;
|
|
31224
31423
|
embedder;
|
|
@@ -31300,7 +31499,7 @@ var Launcher = class {
|
|
|
31300
31499
|
...options.env
|
|
31301
31500
|
};
|
|
31302
31501
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
31303
|
-
this.transport =
|
|
31502
|
+
this.transport = this.floored(options);
|
|
31304
31503
|
this.announcedTraits = JSON.stringify(this.transport.traits);
|
|
31305
31504
|
this.uplink = options.uplink;
|
|
31306
31505
|
this.routes = new Routes(options.uplink?.traits.ipv6 === true);
|
|
@@ -32362,6 +32561,19 @@ var Launcher = class {
|
|
|
32362
32561
|
groupSession(pgid) {
|
|
32363
32562
|
return this.jobs.sessionOf(pgid);
|
|
32364
32563
|
}
|
|
32564
|
+
floored(options) {
|
|
32565
|
+
const { sealedFetch } = options;
|
|
32566
|
+
this.fill = sealedFetch && this.usersMode === "enforce" ? sealedFetcher(sealedFetch, this.fills.signal) : void 0;
|
|
32567
|
+
if (this.fill) this.net.stampProxy(REALM_PROXY_PORT);
|
|
32568
|
+
return placeholderFloor(replayingHops(options.transport ?? missingTransport()), {
|
|
32569
|
+
known: () => this.placeholders,
|
|
32570
|
+
...this.fill ? { fill: this.fill } : {}
|
|
32571
|
+
});
|
|
32572
|
+
}
|
|
32573
|
+
httpFor(pid) {
|
|
32574
|
+
const stamp = this.fill ? () => this.liveStamp(pid) : void 0;
|
|
32575
|
+
return new HttpHandles(this.transport, pid, this.loopbackFor(pid), stamp);
|
|
32576
|
+
}
|
|
32365
32577
|
loopbackFor(pid) {
|
|
32366
32578
|
return new KernelLoopback(
|
|
32367
32579
|
this.net,
|
|
@@ -32369,7 +32581,7 @@ var Launcher = class {
|
|
|
32369
32581
|
const cred = this.credOf(pid);
|
|
32370
32582
|
return { pid, uid: cred.euid, gid: cred.egid };
|
|
32371
32583
|
},
|
|
32372
|
-
() => this.
|
|
32584
|
+
() => this.liveStamp(pid)
|
|
32373
32585
|
);
|
|
32374
32586
|
}
|
|
32375
32587
|
sourceCheck(pid, writer) {
|
|
@@ -32534,7 +32746,7 @@ var Launcher = class {
|
|
|
32534
32746
|
jobs: this.jobs,
|
|
32535
32747
|
ptys: this.ptys,
|
|
32536
32748
|
net: this.net,
|
|
32537
|
-
http:
|
|
32749
|
+
http: this.httpFor(pid),
|
|
32538
32750
|
locks: this.locks,
|
|
32539
32751
|
fifos: this.fifos,
|
|
32540
32752
|
sems: this.sems,
|
|
@@ -32849,6 +33061,19 @@ var Launcher = class {
|
|
|
32849
33061
|
connectorStamp(pid) {
|
|
32850
33062
|
return this.sealed.stamp(this.identityOf(pid), this.credOf(pid), this.tagsOf(pid));
|
|
32851
33063
|
}
|
|
33064
|
+
async liveStamp(pid) {
|
|
33065
|
+
if (!this.creds.has(pid) || this.zombies.has(pid)) return void 0;
|
|
33066
|
+
return this.connectorStamp(pid);
|
|
33067
|
+
}
|
|
33068
|
+
setPlaceholders(list) {
|
|
33069
|
+
if (!Array.isArray(list) || !list.every((p) => typeof p === "string" && p !== "")) {
|
|
33070
|
+
throw fsError("EINVAL", "setPlaceholders takes a list of non-empty strings");
|
|
33071
|
+
}
|
|
33072
|
+
this.placeholders = [...list];
|
|
33073
|
+
}
|
|
33074
|
+
endFills() {
|
|
33075
|
+
this.fills.abort("terminated");
|
|
33076
|
+
}
|
|
32852
33077
|
identityOf(pid) {
|
|
32853
33078
|
const parent = this.jobs.shownParent(pid);
|
|
32854
33079
|
const alive = parent !== void 0 && this.running(parent);
|
|
@@ -32971,7 +33196,7 @@ var Launcher = class {
|
|
|
32971
33196
|
const at = normalizePath(path);
|
|
32972
33197
|
this.unlinked.closed(at);
|
|
32973
33198
|
this.writers?.unlinked.closed(at);
|
|
32974
|
-
const holding = [...this.held].some((
|
|
33199
|
+
const holding = [...this.held].some((holds3) => holds3.holding(at)) || [...this.openFiles].some((open2) => open2.holdsAt(at));
|
|
32975
33200
|
if (!holding) void this.rootFs.announceHolds?.([], [at], false);
|
|
32976
33201
|
const open = [...this.openFiles].some((nodes) => nodes.writes(at)) || heldUnder(this.held, at);
|
|
32977
33202
|
if (!open) void this.mounts.commit(at).catch(() => void 0);
|
|
@@ -33134,8 +33359,9 @@ var Launcher = class {
|
|
|
33134
33359
|
for (const root of roots) this.integrity.forget(root);
|
|
33135
33360
|
this.resetCatalogs();
|
|
33136
33361
|
}
|
|
33137
|
-
attest(path) {
|
|
33362
|
+
attest(path, options = {}) {
|
|
33138
33363
|
return attest(this.rootFs, path, {
|
|
33364
|
+
...options,
|
|
33139
33365
|
users: this.usersMode,
|
|
33140
33366
|
mounts: this.mounts.list().map((entry) => entry.target).filter((target) => this.mounts.mounted(target) !== void 0)
|
|
33141
33367
|
});
|
|
@@ -33192,8 +33418,8 @@ var Launcher = class {
|
|
|
33192
33418
|
for (const name2 of names2 ?? []) {
|
|
33193
33419
|
const path = joinName(real, name2);
|
|
33194
33420
|
if (await this.base.hasOwner(path)) continue;
|
|
33195
|
-
const
|
|
33196
|
-
if (
|
|
33421
|
+
const failed5 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
|
|
33422
|
+
if (failed5 === void 0) removed++;
|
|
33197
33423
|
else left++;
|
|
33198
33424
|
}
|
|
33199
33425
|
if (removed > 0) {
|
|
@@ -33288,7 +33514,7 @@ var Launcher = class {
|
|
|
33288
33514
|
this.pnpmStale();
|
|
33289
33515
|
if (!detach) return;
|
|
33290
33516
|
for (const nodes of this.openFiles) nodes.revoke(at);
|
|
33291
|
-
for (const
|
|
33517
|
+
for (const holds3 of this.held) holds3.revoke(at);
|
|
33292
33518
|
}
|
|
33293
33519
|
unmountAll() {
|
|
33294
33520
|
this.cron.stop();
|
|
@@ -33499,9 +33725,9 @@ var Launcher = class {
|
|
|
33499
33725
|
}
|
|
33500
33726
|
boundTo(path, hidden, fids) {
|
|
33501
33727
|
const keeping = [...this.held].map(
|
|
33502
|
-
(
|
|
33503
|
-
|
|
33504
|
-
fids.flatMap((fid) => [...
|
|
33728
|
+
(holds3) => [
|
|
33729
|
+
holds3,
|
|
33730
|
+
fids.flatMap((fid) => [...holds3.boundAt(path, fid), ...holds3.boundAt(hidden, fid)])
|
|
33505
33731
|
]
|
|
33506
33732
|
).filter(([, ids]) => ids.length > 0);
|
|
33507
33733
|
const nodes = [...this.openFiles].filter(
|
|
@@ -33512,7 +33738,7 @@ var Launcher = class {
|
|
|
33512
33738
|
(open) => fids.some((fid) => open.keepBound([hidden, path], fid, file))
|
|
33513
33739
|
).length;
|
|
33514
33740
|
for (let i = kept; i < nodes.length; i++) file.release();
|
|
33515
|
-
for (const [
|
|
33741
|
+
for (const [holds3, ids] of keeping) holds3.keepBound(ids, path, file);
|
|
33516
33742
|
void this.rootFs.announceHolds?.([], [path, hidden], false);
|
|
33517
33743
|
};
|
|
33518
33744
|
return { keeping, nodes, keep: keep2 };
|
|
@@ -33672,7 +33898,7 @@ var Launcher = class {
|
|
|
33672
33898
|
}
|
|
33673
33899
|
moved(from, to, source) {
|
|
33674
33900
|
this.renameLog.add(from, to);
|
|
33675
|
-
for (const
|
|
33901
|
+
for (const holds3 of this.held) holds3.renamed(from, to);
|
|
33676
33902
|
if (source) return;
|
|
33677
33903
|
for (const nodes of this.openFiles) nodes.renamed(from, to);
|
|
33678
33904
|
this.watchers.moved(from, to);
|
|
@@ -33817,26 +34043,6 @@ function codeOf8(err) {
|
|
|
33817
34043
|
return err?.code;
|
|
33818
34044
|
}
|
|
33819
34045
|
|
|
33820
|
-
// src/body-idle.ts
|
|
33821
|
-
var BODY_IDLE_MS = 5 * 60 * 1e3;
|
|
33822
|
-
function idleFailure(ms) {
|
|
33823
|
-
return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {
|
|
33824
|
-
code: "ETIMEDOUT"
|
|
33825
|
-
});
|
|
33826
|
-
}
|
|
33827
|
-
async function readWithin(reader, ms) {
|
|
33828
|
-
if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();
|
|
33829
|
-
let timer;
|
|
33830
|
-
const idle2 = new Promise((_, reject) => {
|
|
33831
|
-
timer = setTimeout(() => reject(idleFailure(ms)), ms);
|
|
33832
|
-
});
|
|
33833
|
-
try {
|
|
33834
|
-
return await Promise.race([reader.read(), idle2]);
|
|
33835
|
-
} finally {
|
|
33836
|
-
clearTimeout(timer);
|
|
33837
|
-
}
|
|
33838
|
-
}
|
|
33839
|
-
|
|
33840
34046
|
// src/websocket-transport.ts
|
|
33841
34047
|
var SENT_HEADERS_DROP = /* @__PURE__ */ new Set([
|
|
33842
34048
|
"host",
|
|
@@ -34079,7 +34285,21 @@ function headOf(nid, response) {
|
|
|
34079
34285
|
headers: response.headers
|
|
34080
34286
|
};
|
|
34081
34287
|
}
|
|
34082
|
-
function
|
|
34288
|
+
function requestOf(call, signal, uploads) {
|
|
34289
|
+
const { url, method, headers, streamed, body, redirect, nid } = call;
|
|
34290
|
+
return {
|
|
34291
|
+
url,
|
|
34292
|
+
method,
|
|
34293
|
+
headers,
|
|
34294
|
+
...streamed ? { bodyStream: uploads.of(nid, signal) } : body ? { body } : {},
|
|
34295
|
+
...redirect !== void 0 ? { redirect } : {},
|
|
34296
|
+
signal
|
|
34297
|
+
};
|
|
34298
|
+
}
|
|
34299
|
+
function serveTransport(peer, transport, {
|
|
34300
|
+
closeWaitMs = CLOSE_WAIT_MS3,
|
|
34301
|
+
attributed = false
|
|
34302
|
+
} = {}) {
|
|
34083
34303
|
const open = /* @__PURE__ */ new Map();
|
|
34084
34304
|
const fail3 = (nid, e) => {
|
|
34085
34305
|
open.delete(nid);
|
|
@@ -34099,14 +34319,11 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS3 } = {})
|
|
|
34099
34319
|
const entry = { abort };
|
|
34100
34320
|
open.set(call.nid, entry);
|
|
34101
34321
|
try {
|
|
34102
|
-
const response = await transport.fetch(
|
|
34103
|
-
|
|
34104
|
-
|
|
34105
|
-
|
|
34106
|
-
|
|
34107
|
-
...call.redirect !== void 0 ? { redirect: call.redirect } : {},
|
|
34108
|
-
signal: abort.signal
|
|
34109
|
-
});
|
|
34322
|
+
const response = await transport.fetch(
|
|
34323
|
+
requestOf(call, abort.signal, uploads),
|
|
34324
|
+
attributed ? call.owner : void 0,
|
|
34325
|
+
attributed ? call.stamp : void 0
|
|
34326
|
+
);
|
|
34110
34327
|
if (!open.has(call.nid)) {
|
|
34111
34328
|
await response.cancel();
|
|
34112
34329
|
return;
|
|
@@ -34770,21 +34987,21 @@ var BODY_HEADERS = /* @__PURE__ */ new Set([
|
|
|
34770
34987
|
"content-type"
|
|
34771
34988
|
]);
|
|
34772
34989
|
var CREDENTIALS = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2"]);
|
|
34773
|
-
function
|
|
34990
|
+
function failed4(message3) {
|
|
34774
34991
|
return Object.assign(new Error(message3), { status: 502, detail: "transport" });
|
|
34775
34992
|
}
|
|
34776
34993
|
function locationOf(headers) {
|
|
34777
34994
|
return headers.find(([name2]) => name2.toLowerCase() === "location")?.[1];
|
|
34778
34995
|
}
|
|
34779
34996
|
function nextHop(hop, status, location) {
|
|
34780
|
-
if (!URL.canParse(location, hop.url)) throw
|
|
34997
|
+
if (!URL.canParse(location, hop.url)) throw failed4(`a bad redirect from ${hop.url}`);
|
|
34781
34998
|
const next3 = new URL(location, hop.url);
|
|
34782
34999
|
if (next3.protocol !== "http:" && next3.protocol !== "https:") {
|
|
34783
|
-
throw
|
|
35000
|
+
throw failed4(`a redirect from ${hop.url} to ${next3.protocol}`);
|
|
34784
35001
|
}
|
|
34785
35002
|
next3.hash = "";
|
|
34786
35003
|
const toGet = (status === 301 || status === 302) && hop.method === "POST" || status === 303 && hop.method !== "GET" && hop.method !== "HEAD";
|
|
34787
|
-
if (hop.bodyStream && !toGet) throw
|
|
35004
|
+
if (hop.bodyStream && !toGet) throw failed4(`a ${status} redirect would resend a streamed body`);
|
|
34788
35005
|
const crossOrigin = next3.origin !== new URL(hop.url).origin;
|
|
34789
35006
|
const { body, bodyStream: bodyStream2, ...rest2 } = hop;
|
|
34790
35007
|
return {
|
|
@@ -34806,7 +35023,7 @@ async function followRedirects(send2, request) {
|
|
|
34806
35023
|
return hops > 0 ? { ...response, url: hop.url, redirected: true } : response;
|
|
34807
35024
|
}
|
|
34808
35025
|
await response.cancel();
|
|
34809
|
-
if (hops >= MAX_REDIRECTS) throw
|
|
35026
|
+
if (hops >= MAX_REDIRECTS) throw failed4(`too many redirects from ${request.url}`);
|
|
34810
35027
|
hop = nextHop(hop, response.status, location);
|
|
34811
35028
|
}
|
|
34812
35029
|
}
|
|
@@ -34889,7 +35106,7 @@ async function checkDestination(target, policy, resolve2 = resolveHost) {
|
|
|
34889
35106
|
throw refusal2(url, address, place);
|
|
34890
35107
|
}
|
|
34891
35108
|
}
|
|
34892
|
-
function
|
|
35109
|
+
function guarded3(check, signal) {
|
|
34893
35110
|
if (!signal) return check;
|
|
34894
35111
|
signal.throwIfAborted();
|
|
34895
35112
|
let stop = () => {
|
|
@@ -34976,11 +35193,11 @@ function ensureSubscribed() {
|
|
|
34976
35193
|
function guardedLoopback(transport, policy, resolve2) {
|
|
34977
35194
|
ensureSubscribed();
|
|
34978
35195
|
const open = transport.websocket?.bind(transport);
|
|
34979
|
-
const send2 = async (request, owner) => {
|
|
34980
|
-
await
|
|
35196
|
+
const send2 = async (request, owner, stamp) => {
|
|
35197
|
+
await guarded3(checkDestination(request.url, policy, resolve2), request.signal);
|
|
34981
35198
|
const entry = { policy };
|
|
34982
35199
|
try {
|
|
34983
|
-
return await loopbackStore.run(entry, () => transport.fetch(request, owner));
|
|
35200
|
+
return await loopbackStore.run(entry, () => transport.fetch(request, owner, stamp));
|
|
34984
35201
|
} catch (err) {
|
|
34985
35202
|
throw entry.refused ?? err;
|
|
34986
35203
|
}
|
|
@@ -34989,10 +35206,10 @@ function guardedLoopback(transport, policy, resolve2) {
|
|
|
34989
35206
|
get traits() {
|
|
34990
35207
|
return transport.traits;
|
|
34991
35208
|
},
|
|
34992
|
-
fetch: (request, owner) => request.redirect === "follow" ? followRedirects((hop) => send2(hop, owner), request) : send2(request, owner),
|
|
35209
|
+
fetch: (request, owner, stamp) => request.redirect === "follow" ? followRedirects((hop) => send2(hop, owner, stamp), request) : send2(request, owner, stamp),
|
|
34993
35210
|
...open ? {
|
|
34994
35211
|
websocket: async (request) => {
|
|
34995
|
-
await
|
|
35212
|
+
await guarded3(checkDestination(request.url, policy, resolve2), request.signal);
|
|
34996
35213
|
const entry = { policy };
|
|
34997
35214
|
try {
|
|
34998
35215
|
return await loopbackStore.run(entry, () => open(request));
|
|
@@ -36376,6 +36593,7 @@ function checkedRequests(hook) {
|
|
|
36376
36593
|
return { kinds, handle: (request) => hook.handle(request) };
|
|
36377
36594
|
}
|
|
36378
36595
|
async function createNodeKernel(options = {}) {
|
|
36596
|
+
const hooks = sealedHooks(options.sealed);
|
|
36379
36597
|
const root = options.root ?? memoryRoot();
|
|
36380
36598
|
const fs = new OpfsFs(root, void 0, void 0, { ranged: isMemoryRoot(root) });
|
|
36381
36599
|
await fs.reconcile();
|
|
@@ -36414,7 +36632,8 @@ async function createNodeKernel(options = {}) {
|
|
|
36414
36632
|
users: options.users === void 0 ? DEFAULT_USERS : options.users,
|
|
36415
36633
|
...options.onDenial ? { onDenial: options.onDenial } : {},
|
|
36416
36634
|
...options.protect ? { protect: options.protect } : {},
|
|
36417
|
-
...
|
|
36635
|
+
...hooks.request ? { sealed: hooks.request } : {},
|
|
36636
|
+
...hooks.fetch ? { sealedFetch: hooks.fetch } : {},
|
|
36418
36637
|
...options.clipboard ? { clipboard: options.clipboard } : {},
|
|
36419
36638
|
...options.requests ? { embedder: checkedRequests(options.requests) } : {},
|
|
36420
36639
|
...options.approve ? { approve: options.approve } : {},
|
|
@@ -36490,6 +36709,8 @@ async function createNodeKernel(options = {}) {
|
|
|
36490
36709
|
},
|
|
36491
36710
|
chmod: async (path, mode) => launcher.fs.chmod(path, modeOption(mode)),
|
|
36492
36711
|
integrity: { revoke: (path) => guard2(() => launcher.revokeIntegrity(path)) },
|
|
36712
|
+
sealed: { setPlaceholders: (list) => guard2(async () => launcher.setPlaceholders(list)) },
|
|
36713
|
+
attest: ((path, attestOptions) => guard2(() => launcher.attest(path, attestOptions))),
|
|
36493
36714
|
readFile: async (path) => launcher.fs.readFileBuffer(path),
|
|
36494
36715
|
mount: (spec) => guard2(() => launcher.mount(spec)),
|
|
36495
36716
|
umount: (target) => guard2(async () => launcher.umount(target)),
|
|
@@ -36522,6 +36743,7 @@ async function createNodeKernel(options = {}) {
|
|
|
36522
36743
|
for (const reject of [...pending]) reject(new Error(TERMINATED));
|
|
36523
36744
|
for (const kill of [...live]) kill();
|
|
36524
36745
|
launcher.cdp.close();
|
|
36746
|
+
launcher.endFills();
|
|
36525
36747
|
launcher.unmountAll();
|
|
36526
36748
|
dropCache(cache);
|
|
36527
36749
|
}
|
|
@@ -36531,6 +36753,7 @@ export {
|
|
|
36531
36753
|
KernelCallError,
|
|
36532
36754
|
KernelGoneError,
|
|
36533
36755
|
MAX_WARM_WORKERS,
|
|
36756
|
+
SEALED_FETCH_VERSION,
|
|
36534
36757
|
WARM_IDLE_MS,
|
|
36535
36758
|
attachKernel,
|
|
36536
36759
|
createNodeKernel,
|