@ai-ecoverse/slicc-kernel 1.129.0 → 1.130.1
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 +21 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +256 -59
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +236 -79
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +256 -59
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +216 -62
- package/dist/process-worker.js.map +4 -4
- package/dist/types/fs/changes.d.ts +1 -0
- package/dist/types/fs/remote.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/kernel/js-threads.d.ts +38 -0
- package/dist/types/kernel/protocol.d.ts +35 -0
- package/dist/types/launcher.d.ts +1 -0
- package/dist/types/process/js/js-context.d.ts +3 -0
- package/dist/types/process/js/js-thread.d.ts +22 -0
- package/dist/types/process/wasi/wasi-files.d.ts +1 -0
- package/package.json +2 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -636,8 +636,8 @@ var Integrity = class {
|
|
|
636
636
|
}
|
|
637
637
|
}
|
|
638
638
|
async expected(path) {
|
|
639
|
-
const
|
|
640
|
-
return typeof
|
|
639
|
+
const answer2 = await this.lookup(path);
|
|
640
|
+
return typeof answer2 === "string" ? answer2.toLowerCase() : void 0;
|
|
641
641
|
}
|
|
642
642
|
say(event) {
|
|
643
643
|
try {
|
|
@@ -890,10 +890,12 @@ var RemoteWatch = class {
|
|
|
890
890
|
quiet;
|
|
891
891
|
crowd;
|
|
892
892
|
told;
|
|
893
|
+
counted = 0;
|
|
893
894
|
recount() {
|
|
894
895
|
const now = this.crowded();
|
|
895
|
-
if (now === this.told) return;
|
|
896
|
+
if (now === this.told && this.peers.size === this.counted) return;
|
|
896
897
|
this.told = now;
|
|
898
|
+
this.counted = this.peers.size;
|
|
897
899
|
this.crowd?.(now);
|
|
898
900
|
}
|
|
899
901
|
constructor(name2, options = {}) {
|
|
@@ -983,12 +985,12 @@ var RemoteWatch = class {
|
|
|
983
985
|
}
|
|
984
986
|
greeted(peer) {
|
|
985
987
|
this.arrived(peer);
|
|
986
|
-
const
|
|
988
|
+
const answer2 = () => {
|
|
987
989
|
this.channel.postMessage({ here: this.tab, to: peer });
|
|
988
990
|
if (this.mine.length > 0) void this.announce(this.mine);
|
|
989
991
|
};
|
|
990
|
-
if (this.quiet) void this.quiet().then(
|
|
991
|
-
else
|
|
992
|
+
if (this.quiet) void this.quiet().then(answer2, answer2);
|
|
993
|
+
else answer2();
|
|
992
994
|
}
|
|
993
995
|
announced({ tab, paths, seq: seq2 }) {
|
|
994
996
|
const from = tab;
|
|
@@ -7020,7 +7022,7 @@ function satisfies(version, range2) {
|
|
|
7020
7022
|
}
|
|
7021
7023
|
|
|
7022
7024
|
// src/version.ts
|
|
7023
|
-
var KERNEL_VERSION = true ? "1.
|
|
7025
|
+
var KERNEL_VERSION = true ? "1.130.1" : "0.0.0-dev";
|
|
7024
7026
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7025
7027
|
function procVersion() {
|
|
7026
7028
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9414,6 +9416,9 @@ var FileChanges = class {
|
|
|
9414
9416
|
foreign(on) {
|
|
9415
9417
|
Atomics.store(this.view, FOREIGN, on ? 1 : 0);
|
|
9416
9418
|
}
|
|
9419
|
+
flush() {
|
|
9420
|
+
Atomics.add(this.view, GEN, RING_SIZE + 1);
|
|
9421
|
+
}
|
|
9417
9422
|
publish(...paths) {
|
|
9418
9423
|
for (const path of paths) {
|
|
9419
9424
|
const g = Atomics.add(this.view, GEN, 1) + 1 | 0;
|
|
@@ -16336,11 +16341,11 @@ function carriesUdp(uplink) {
|
|
|
16336
16341
|
return uplink.traits.udp === true && typeof uplink.udp === "function";
|
|
16337
16342
|
}
|
|
16338
16343
|
function answerOf(result) {
|
|
16339
|
-
const
|
|
16340
|
-
const addresses = Array.isArray(
|
|
16344
|
+
const answer2 = Array.isArray(result) ? { addresses: result } : result;
|
|
16345
|
+
const addresses = Array.isArray(answer2?.addresses) ? answer2.addresses.filter((a) => typeof a === "string") : [];
|
|
16341
16346
|
return {
|
|
16342
16347
|
addresses,
|
|
16343
|
-
...typeof
|
|
16348
|
+
...typeof answer2?.ttl === "number" && answer2.ttl >= 0 ? { ttl: answer2.ttl } : {}
|
|
16344
16349
|
};
|
|
16345
16350
|
}
|
|
16346
16351
|
var NEVER = new Routes(true);
|
|
@@ -16528,9 +16533,9 @@ var Resolver = class {
|
|
|
16528
16533
|
async lookup(name2, family, id2, abandoned) {
|
|
16529
16534
|
const uplink = this.uplink;
|
|
16530
16535
|
const timeout = AbortSignal.any([AbortSignal.timeout(this.timeoutMs), abandoned]);
|
|
16531
|
-
let
|
|
16536
|
+
let answer2;
|
|
16532
16537
|
try {
|
|
16533
|
-
|
|
16538
|
+
answer2 = answerOf(
|
|
16534
16539
|
await Promise.race([
|
|
16535
16540
|
uplink.resolve(name2, family, timeout),
|
|
16536
16541
|
new Promise(
|
|
@@ -16541,8 +16546,8 @@ var Resolver = class {
|
|
|
16541
16546
|
} catch {
|
|
16542
16547
|
return [];
|
|
16543
16548
|
}
|
|
16544
|
-
const addresses =
|
|
16545
|
-
if (addresses.length > 0) this.remember(id2, addresses,
|
|
16549
|
+
const addresses = answer2.addresses.filter((a) => this.usable(name2, a, family));
|
|
16550
|
+
if (addresses.length > 0) this.remember(id2, addresses, answer2.ttl);
|
|
16546
16551
|
return addresses;
|
|
16547
16552
|
}
|
|
16548
16553
|
usable(name2, address, family) {
|
|
@@ -21198,8 +21203,8 @@ var WasmProcess = class {
|
|
|
21198
21203
|
spares(sig) {
|
|
21199
21204
|
const { caught, ignored } = this.signalMasks();
|
|
21200
21205
|
const bit = isSignal(sig) ? sigbit(sig) : 0;
|
|
21201
|
-
const
|
|
21202
|
-
return { ok: true, kind: "json", json:
|
|
21206
|
+
const answer2 = (ignored & bit) !== 0 ? "ignore" : (caught & bit) !== 0 ? "spare" : "terminate";
|
|
21207
|
+
return { ok: true, kind: "json", json: answer2 };
|
|
21203
21208
|
}
|
|
21204
21209
|
async killSelf(sig, target, probe) {
|
|
21205
21210
|
if (!this.options.exitSignal) throw new KernelError("ENOSYS");
|
|
@@ -22316,10 +22321,10 @@ var WasmProcess = class {
|
|
|
22316
22321
|
cwd: typeof req.cwd === "string" && req.cwd.startsWith("/") ? req.cwd : "/",
|
|
22317
22322
|
...typeof req.term === "string" ? { term: req.term } : {}
|
|
22318
22323
|
};
|
|
22319
|
-
const
|
|
22320
|
-
if (!("grant" in
|
|
22324
|
+
const answer2 = await sudo(call, this.blockingSignal(cancelled));
|
|
22325
|
+
if (!("grant" in answer2)) return answer2;
|
|
22321
22326
|
if (this.dying) throw new KernelError("EINTR");
|
|
22322
|
-
const { file, argv, env, cwd, cred, caller } =
|
|
22327
|
+
const { file, argv, env, cwd, cred, caller } = answer2.grant;
|
|
22323
22328
|
const stdio = [{ fd: 0 }, { fd: 1 }, { fd: 2 }];
|
|
22324
22329
|
return {
|
|
22325
22330
|
pid: await this.children.spawn({ file, argv, env, cwd, pgid: 0 }, stdio, [], {
|
|
@@ -22479,6 +22484,153 @@ var WASM_THREAD_SPAWN = "wasm-thread-spawn";
|
|
|
22479
22484
|
var WASM_THREAD_INIT = "wasm-thread-init";
|
|
22480
22485
|
var WASM_THREAD_EXIT = "wasm-thread-exit";
|
|
22481
22486
|
var WASM_MAX_THREADS = 256;
|
|
22487
|
+
var JS_THREAD_SPAWN = "js-thread-spawn";
|
|
22488
|
+
var JS_THREAD_INIT = "js-thread-init";
|
|
22489
|
+
var JS_THREAD_EXIT = "js-thread-exit";
|
|
22490
|
+
var JS_MAX_THREADS = 256;
|
|
22491
|
+
var JS_DEFAULT_THREADS = 16;
|
|
22492
|
+
var JS_THREAD_NO_MEMORY = 256;
|
|
22493
|
+
var JS_THREAD_CRASHED = 257;
|
|
22494
|
+
|
|
22495
|
+
// src/kernel/js-threads.ts
|
|
22496
|
+
var JS_OOM = /out of memory|Array buffer allocation failed|Cannot allocate Wasm memory|could not allocate memory|ERR_WORKER_OUT_OF_MEMORY/i;
|
|
22497
|
+
var ENDING = { ok: false, errno: "EINTR", message: "the thread is ending" };
|
|
22498
|
+
var MAIN_ONLY = { ok: true, kind: "void" };
|
|
22499
|
+
function track(ops, req, result) {
|
|
22500
|
+
if (req.op === "async-submit" && result.ok && result.kind === "json") {
|
|
22501
|
+
if (typeof result.json === "number") ops.set(result.json, req.token);
|
|
22502
|
+
} else if (req.op === "async-cancel" || req.op === "async-take" && (result.ok || result.errno !== "EAGAIN")) {
|
|
22503
|
+
ops.delete(req.id);
|
|
22504
|
+
}
|
|
22505
|
+
}
|
|
22506
|
+
function cores() {
|
|
22507
|
+
const n = globalThis.navigator?.hardwareConcurrency;
|
|
22508
|
+
return typeof n === "number" && Number.isInteger(n) && n > 0 ? n : 0;
|
|
22509
|
+
}
|
|
22510
|
+
function jsThreadCap(env) {
|
|
22511
|
+
const asked = Number.parseInt(env.SLICC_JS_THREADS ?? "", 10);
|
|
22512
|
+
if (asked >= 1) return Math.min(asked, JS_MAX_THREADS);
|
|
22513
|
+
return Math.min(JS_MAX_THREADS, Math.max(JS_DEFAULT_THREADS, 2 * cores()));
|
|
22514
|
+
}
|
|
22515
|
+
function codeOf4(code) {
|
|
22516
|
+
if (code === JS_THREAD_NO_MEMORY || code === JS_THREAD_CRASHED) return code;
|
|
22517
|
+
return typeof code === "number" && Number.isInteger(code) ? code & 255 : JS_THREAD_CRASHED;
|
|
22518
|
+
}
|
|
22519
|
+
function answer(control, message3) {
|
|
22520
|
+
control.postMessage(message3);
|
|
22521
|
+
}
|
|
22522
|
+
var JsThreads = class {
|
|
22523
|
+
deps;
|
|
22524
|
+
live = /* @__PURE__ */ new Map();
|
|
22525
|
+
headers = /* @__PURE__ */ new Map();
|
|
22526
|
+
frozen = false;
|
|
22527
|
+
last = 0;
|
|
22528
|
+
closed = false;
|
|
22529
|
+
constructor(deps) {
|
|
22530
|
+
this.deps = deps;
|
|
22531
|
+
}
|
|
22532
|
+
get size() {
|
|
22533
|
+
return this.live.size;
|
|
22534
|
+
}
|
|
22535
|
+
spawn(msg) {
|
|
22536
|
+
const { control, port } = msg;
|
|
22537
|
+
if (this.closed || this.live.size >= this.deps.cap) {
|
|
22538
|
+
answer(
|
|
22539
|
+
control,
|
|
22540
|
+
this.closed ? { errno: "ESRCH", message: "the process is ending" } : { errno: "EAGAIN", message: `more than ${this.deps.cap} threads` }
|
|
22541
|
+
);
|
|
22542
|
+
control.close();
|
|
22543
|
+
port.close();
|
|
22544
|
+
return;
|
|
22545
|
+
}
|
|
22546
|
+
const tid = ++this.last;
|
|
22547
|
+
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
22548
|
+
const header3 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
22549
|
+
if (this.frozen) Atomics.store(header3, SAB_I_STOP, 1);
|
|
22550
|
+
const worker = this.deps.createWorker();
|
|
22551
|
+
const clock = this.deps.clocks.thread(tid + 1, sab);
|
|
22552
|
+
let ended = false;
|
|
22553
|
+
const end = (code) => {
|
|
22554
|
+
if (ended) return;
|
|
22555
|
+
ended = true;
|
|
22556
|
+
this.live.delete(tid);
|
|
22557
|
+
this.headers.delete(tid);
|
|
22558
|
+
this.deps.wakes.delete(header3);
|
|
22559
|
+
for (const [id2, token] of ops) {
|
|
22560
|
+
void this.deps.dispatch({ op: "async-cancel", id: id2, token });
|
|
22561
|
+
}
|
|
22562
|
+
ops.clear();
|
|
22563
|
+
worker.removeEventListener("message", onMessage);
|
|
22564
|
+
worker.removeEventListener("error", onError);
|
|
22565
|
+
control.removeEventListener("message", onControl);
|
|
22566
|
+
responder.dispose();
|
|
22567
|
+
lane.dispose();
|
|
22568
|
+
this.deps.clocks.threadEnded(tid + 1);
|
|
22569
|
+
worker.terminate();
|
|
22570
|
+
answer(control, { exited: code });
|
|
22571
|
+
control.close();
|
|
22572
|
+
};
|
|
22573
|
+
const ops = /* @__PURE__ */ new Map();
|
|
22574
|
+
const dispatch2 = async (req, block) => {
|
|
22575
|
+
if (isWasmSyscall(req) && req.op === "proc-exit") {
|
|
22576
|
+
queueMicrotask(() => end(req.status & 255));
|
|
22577
|
+
return ENDING;
|
|
22578
|
+
}
|
|
22579
|
+
if (isWasmSyscall(req) && req.op === "sig-mask") return MAIN_ONLY;
|
|
22580
|
+
const result = await this.deps.dispatch(req, block);
|
|
22581
|
+
if (!ended) track(ops, req, result);
|
|
22582
|
+
return result;
|
|
22583
|
+
};
|
|
22584
|
+
const responder = this.deps.attach(worker, sab, this.deps.clocks.timed(clock, dispatch2));
|
|
22585
|
+
const lane = this.deps.openLane(dispatch2);
|
|
22586
|
+
const onMessage = (event) => {
|
|
22587
|
+
const data = event.data;
|
|
22588
|
+
if (data?.type === JS_THREAD_EXIT) end(codeOf4(data.code));
|
|
22589
|
+
else if (data?.type === JS_THREAD_SPAWN) this.spawn(event.data);
|
|
22590
|
+
else if (data?.type === WASM_PROCESS_ERROR) this.crashed(String(data.message), end);
|
|
22591
|
+
};
|
|
22592
|
+
const onError = (event) => {
|
|
22593
|
+
event.preventDefault();
|
|
22594
|
+
this.crashed(String(event.message ?? "worker error"), end);
|
|
22595
|
+
};
|
|
22596
|
+
const onControl = (event) => {
|
|
22597
|
+
if (event.data?.terminate === true) end(1);
|
|
22598
|
+
};
|
|
22599
|
+
worker.addEventListener("message", onMessage);
|
|
22600
|
+
worker.addEventListener("error", onError);
|
|
22601
|
+
control.addEventListener("message", onControl);
|
|
22602
|
+
control.start();
|
|
22603
|
+
this.live.set(tid, end);
|
|
22604
|
+
this.headers.set(tid, header3);
|
|
22605
|
+
this.deps.wakes.add(header3);
|
|
22606
|
+
const init = {
|
|
22607
|
+
...this.deps.init(sab, lane.lane),
|
|
22608
|
+
type: JS_THREAD_INIT,
|
|
22609
|
+
thread: { tid, port, data: msg.data }
|
|
22610
|
+
};
|
|
22611
|
+
try {
|
|
22612
|
+
worker.postMessage(init, [lane.lane.port, port, ...msg.transfer ?? []]);
|
|
22613
|
+
} catch {
|
|
22614
|
+
end(JS_THREAD_CRASHED);
|
|
22615
|
+
return;
|
|
22616
|
+
}
|
|
22617
|
+
answer(control, { tid });
|
|
22618
|
+
}
|
|
22619
|
+
crashed(message3, end) {
|
|
22620
|
+
end(JS_OOM.test(message3) ? JS_THREAD_NO_MEMORY : JS_THREAD_CRASHED);
|
|
22621
|
+
}
|
|
22622
|
+
stopped(stopped) {
|
|
22623
|
+
this.frozen = stopped;
|
|
22624
|
+
for (const header3 of this.headers.values()) {
|
|
22625
|
+
Atomics.store(header3, SAB_I_STOP, stopped ? 1 : 0);
|
|
22626
|
+
Atomics.notify(header3, SAB_I_STOP);
|
|
22627
|
+
}
|
|
22628
|
+
}
|
|
22629
|
+
close() {
|
|
22630
|
+
this.closed = true;
|
|
22631
|
+
for (const end of [...this.live.values()]) end(1);
|
|
22632
|
+
}
|
|
22633
|
+
};
|
|
22482
22634
|
|
|
22483
22635
|
// src/kernel/host.ts
|
|
22484
22636
|
var CRASHED = 70;
|
|
@@ -22581,6 +22733,7 @@ function threadSignalsOf(sab) {
|
|
|
22581
22733
|
function threadCancel(thread) {
|
|
22582
22734
|
return unblocked(thread.header) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
22583
22735
|
}
|
|
22736
|
+
var asyncFanout = /* @__PURE__ */ new WeakMap();
|
|
22584
22737
|
function notifiers(header3) {
|
|
22585
22738
|
return {
|
|
22586
22739
|
onPending(sig) {
|
|
@@ -22588,8 +22741,10 @@ function notifiers(header3) {
|
|
|
22588
22741
|
Atomics.notify(header3, SAB_I_SIGNALS);
|
|
22589
22742
|
},
|
|
22590
22743
|
onAsync() {
|
|
22591
|
-
|
|
22592
|
-
|
|
22744
|
+
for (const at of [header3, ...asyncFanout.get(header3) ?? []]) {
|
|
22745
|
+
Atomics.add(at, SAB_I_ASYNC, 1);
|
|
22746
|
+
Atomics.notify(at, SAB_I_ASYNC);
|
|
22747
|
+
}
|
|
22593
22748
|
}
|
|
22594
22749
|
};
|
|
22595
22750
|
}
|
|
@@ -22820,6 +22975,7 @@ function spawnWasmProcess(opts) {
|
|
|
22820
22975
|
dispatch: clocks.timed(void 0, dispatch2)
|
|
22821
22976
|
});
|
|
22822
22977
|
const lane = opts.program.abi === "js" ? openLane(token, dispatch2) : void 0;
|
|
22978
|
+
const jsThreads = jsThreadsOf(opts, process, token, dispatch2, clocks, header3);
|
|
22823
22979
|
const { promise: exited, resolve: settle3 } = Promise.withResolvers();
|
|
22824
22980
|
let done5 = false;
|
|
22825
22981
|
let endedBy;
|
|
@@ -22833,6 +22989,7 @@ function spawnWasmProcess(opts) {
|
|
|
22833
22989
|
worker.removeEventListener("message", onMessage);
|
|
22834
22990
|
worker.removeEventListener("error", onError);
|
|
22835
22991
|
for (const tid of [...threads.keys()]) endThread(tid);
|
|
22992
|
+
jsThreads?.close();
|
|
22836
22993
|
responder.dispose();
|
|
22837
22994
|
lane?.dispose();
|
|
22838
22995
|
revokeSyncFsToken(token);
|
|
@@ -22856,6 +23013,8 @@ function spawnWasmProcess(opts) {
|
|
|
22856
23013
|
finish(...dying.status(data.code));
|
|
22857
23014
|
} else if (data?.type === WASM_THREAD_SPAWN && data.thread) {
|
|
22858
23015
|
spawnThread(data.thread);
|
|
23016
|
+
} else if (data?.type === JS_THREAD_SPAWN && jsThreads) {
|
|
23017
|
+
jsThreads.spawn(data);
|
|
22859
23018
|
}
|
|
22860
23019
|
};
|
|
22861
23020
|
const onMessage = (event) => handle(event.data);
|
|
@@ -22929,13 +23088,35 @@ function spawnWasmProcess(opts) {
|
|
|
22929
23088
|
termsig: () => endedBy,
|
|
22930
23089
|
onState: (listener) => process.onState(listener),
|
|
22931
23090
|
memory: () => Atomics.load(header3, SAB_I_MEMORY) * 65536,
|
|
23091
|
+
...processViews(process, opts, header3),
|
|
23092
|
+
writesBack: () => opts.program.abi === "wasi" && !done5,
|
|
23093
|
+
...clockViews(clocks)
|
|
23094
|
+
};
|
|
23095
|
+
}
|
|
23096
|
+
function jsThreadsOf(opts, process, token, dispatch2, clocks, header3) {
|
|
23097
|
+
if (opts.program.abi !== "js") return void 0;
|
|
23098
|
+
const wakes = /* @__PURE__ */ new Set();
|
|
23099
|
+
asyncFanout.set(header3, wakes);
|
|
23100
|
+
const threads = new JsThreads({
|
|
23101
|
+
wakes,
|
|
23102
|
+
cap: jsThreadCap(opts.env),
|
|
23103
|
+
createWorker: opts.createWorker,
|
|
23104
|
+
init: (sab, lane) => processInit(opts, sab, process.umask, copyCred(process.cred), lane),
|
|
23105
|
+
openLane: (laneDispatch) => openLane(token, laneDispatch),
|
|
23106
|
+
attach: (worker, sab, threadDispatch) => attachSyncSabResponder(worker, sab, token, { dispatch: threadDispatch }),
|
|
23107
|
+
dispatch: dispatch2,
|
|
23108
|
+
clocks
|
|
23109
|
+
});
|
|
23110
|
+
process.onState((state) => threads.stopped(state === "stopped"));
|
|
23111
|
+
return threads;
|
|
23112
|
+
}
|
|
23113
|
+
function processViews(process, opts, header3) {
|
|
23114
|
+
return {
|
|
22932
23115
|
ignoredSignals: (fork) => process.inheritable(fork),
|
|
22933
23116
|
blockedSignals: () => opts.program.abi === "wasi" ? loadBlocked(header3) : [0, 0],
|
|
22934
23117
|
signalMasks: () => process.signalMasks(),
|
|
22935
23118
|
umask: () => process.umask,
|
|
22936
|
-
cred: () => copyCred(process.cred)
|
|
22937
|
-
writesBack: () => opts.program.abi === "wasi" && !done5,
|
|
22938
|
-
...clockViews(clocks)
|
|
23119
|
+
cred: () => copyCred(process.cred)
|
|
22939
23120
|
};
|
|
22940
23121
|
}
|
|
22941
23122
|
function clockViews(clocks) {
|
|
@@ -24253,8 +24434,8 @@ var FSA_CAPABILITIES = {
|
|
|
24253
24434
|
ranges: true,
|
|
24254
24435
|
sessions: true
|
|
24255
24436
|
};
|
|
24256
|
-
var
|
|
24257
|
-
var denied = (err) =>
|
|
24437
|
+
var codeOf5 = (err) => err?.code;
|
|
24438
|
+
var denied = (err) => codeOf5(err) === "EACCES" || err?.name === "NotAllowedError";
|
|
24258
24439
|
function attrOf(st) {
|
|
24259
24440
|
return {
|
|
24260
24441
|
kind: st.isDirectory ? "directory" : st.isSymbolicLink ? "symlink" : "file",
|
|
@@ -24276,7 +24457,7 @@ function kernelFsHandlers(fs) {
|
|
|
24276
24457
|
try {
|
|
24277
24458
|
return await fs.stat(path);
|
|
24278
24459
|
} catch (err) {
|
|
24279
|
-
if (
|
|
24460
|
+
if (codeOf5(err) === "ENOENT") return void 0;
|
|
24280
24461
|
throw err;
|
|
24281
24462
|
}
|
|
24282
24463
|
}
|
|
@@ -24469,7 +24650,7 @@ function parseFstab(text) {
|
|
|
24469
24650
|
});
|
|
24470
24651
|
return lines2;
|
|
24471
24652
|
}
|
|
24472
|
-
function
|
|
24653
|
+
function codeOf6(err) {
|
|
24473
24654
|
const code = err?.code;
|
|
24474
24655
|
return typeof code === "string" ? code : "EIO";
|
|
24475
24656
|
}
|
|
@@ -24507,18 +24688,18 @@ async function mountLine({ line, spec, invalid }, mount, signal, retries, discar
|
|
|
24507
24688
|
break;
|
|
24508
24689
|
} catch (err) {
|
|
24509
24690
|
failed3 = err;
|
|
24510
|
-
if (FINAL.has(
|
|
24691
|
+
if (FINAL.has(codeOf6(err)) || attempt === retries.length) break;
|
|
24511
24692
|
await wait(retries[attempt], signal);
|
|
24512
24693
|
}
|
|
24513
24694
|
}
|
|
24514
|
-
const code =
|
|
24695
|
+
const code = codeOf6(failed3);
|
|
24515
24696
|
return { line, target: spec.target, code, error: String(failed3?.message ?? code) };
|
|
24516
24697
|
}
|
|
24517
24698
|
|
|
24518
24699
|
// src/mount/hostfs.ts
|
|
24519
24700
|
var HOSTFS_IO = 16 * 1024 * 1024;
|
|
24520
|
-
var
|
|
24521
|
-
var unreachable = (err) =>
|
|
24701
|
+
var codeOf7 = (err) => err?.code;
|
|
24702
|
+
var unreachable = (err) => codeOf7(err) === "ENOTCONN";
|
|
24522
24703
|
function rel(path) {
|
|
24523
24704
|
return path.replace(/^\/+/, "");
|
|
24524
24705
|
}
|
|
@@ -24695,7 +24876,7 @@ function hostfsHandlers(current, againMs = RESTORE_AGAIN_MS) {
|
|
|
24695
24876
|
try {
|
|
24696
24877
|
return { opened: await opening2(), restore: void 0 };
|
|
24697
24878
|
} catch (err) {
|
|
24698
|
-
if (!flags2.write ||
|
|
24879
|
+
if (!flags2.write || codeOf7(err) !== "EACCES") throw err;
|
|
24699
24880
|
const was = await client.call("stat", { path: rel(path) });
|
|
24700
24881
|
const mode = was.mode ?? 0;
|
|
24701
24882
|
if (mode & 128) throw err;
|
|
@@ -25915,14 +26096,14 @@ var Sudo = class {
|
|
|
25915
26096
|
if (this.pending.has(cred.ruid)) return failed2("EBUSY", "sudo: another request is pending");
|
|
25916
26097
|
this.pending.add(cred.ruid);
|
|
25917
26098
|
try {
|
|
25918
|
-
const
|
|
25919
|
-
if (typeof
|
|
26099
|
+
const answer2 = await this.ask(caller, self, target, parsed2.command, path, cwd, signal);
|
|
26100
|
+
if (typeof answer2 !== "string") return answer2;
|
|
25920
26101
|
if (await this.canonical(call.cwd) !== cwd || !await this.reachable(cred, cwd)) {
|
|
25921
26102
|
return failed2("EACCES", `sudo: ${call.cwd} changed while the request waited`);
|
|
25922
26103
|
}
|
|
25923
26104
|
const changed = await this.untrusted(path, cwd, word);
|
|
25924
26105
|
if (changed) return changed;
|
|
25925
|
-
if (
|
|
26106
|
+
if (answer2 === "always" && !await this.remember(self, target, cwd, argv)) {
|
|
25926
26107
|
return failed2("EIO", "sudo: the rule could not be recorded");
|
|
25927
26108
|
}
|
|
25928
26109
|
return grant();
|
|
@@ -25977,11 +26158,11 @@ ${lines2}
|
|
|
25977
26158
|
);
|
|
25978
26159
|
try {
|
|
25979
26160
|
const answered2 = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
|
|
25980
|
-
const
|
|
25981
|
-
if (
|
|
26161
|
+
const answer2 = await Promise.race([answered2, aborted2]);
|
|
26162
|
+
if (answer2 === "aborted" || control.signal.aborted) {
|
|
25982
26163
|
return control.signal.reason === "expired" ? failed2("ETIMEDOUT", "sudo: the request expired") : failed2("EINTR", "sudo: the request was withdrawn");
|
|
25983
26164
|
}
|
|
25984
|
-
return
|
|
26165
|
+
return answer2 === "once" || answer2 === "always" ? answer2 : failed2("EACCES", "sudo: approval denied");
|
|
25985
26166
|
} finally {
|
|
25986
26167
|
clearTimeout(timer);
|
|
25987
26168
|
requester.removeEventListener("abort", withdraw);
|
|
@@ -26393,9 +26574,7 @@ var Launcher = class {
|
|
|
26393
26574
|
this.usersMode = usersMode(options.users);
|
|
26394
26575
|
this.memories = memoriesOf(options.wasmMemories);
|
|
26395
26576
|
this.rootFs = options.fs;
|
|
26396
|
-
|
|
26397
|
-
this.locks = kernelLocks(options.fs.rootName, peers);
|
|
26398
|
-
peers?.watch((crowded) => this.changes.foreign(crowded));
|
|
26577
|
+
this.locks = kernelLocks(options.fs.rootName, this.flushingPeers(options.fs));
|
|
26399
26578
|
this.dac = this.usersMode === "off" ? void 0 : new Dac(this.usersMode, options.onDenial);
|
|
26400
26579
|
if (this.dac) this.dac.tagOf = (pid) => this.tagOf(pid);
|
|
26401
26580
|
this.clipboard = new ClipboardBroker(
|
|
@@ -26481,7 +26660,10 @@ var Launcher = class {
|
|
|
26481
26660
|
this.nodes.keepsOnDisk = true;
|
|
26482
26661
|
this.openFiles.add(this.nodes);
|
|
26483
26662
|
options.fs.onPeer?.(() => this.flushOpen());
|
|
26484
|
-
options.fs.remoteChanges?.((change) =>
|
|
26663
|
+
options.fs.remoteChanges?.((change) => {
|
|
26664
|
+
this.changes.flush();
|
|
26665
|
+
this.rewritten(change.paths);
|
|
26666
|
+
});
|
|
26485
26667
|
const holders = [this.held, this.openFiles];
|
|
26486
26668
|
this.unlinked = new UnlinkedKeeper(
|
|
26487
26669
|
fs,
|
|
@@ -26896,7 +27078,7 @@ var Launcher = class {
|
|
|
26896
27078
|
try {
|
|
26897
27079
|
return await this.planOne(req, ctx);
|
|
26898
27080
|
} catch (err) {
|
|
26899
|
-
const code =
|
|
27081
|
+
const code = codeOf8(err);
|
|
26900
27082
|
const searched = bare && req.search !== false && (code === "ENOENT" || code === "ENOEXEC");
|
|
26901
27083
|
if (!searched || await this.commandAt(req.file, ctx.scope)) throw err;
|
|
26902
27084
|
const found = await this.onPath(req, ctx);
|
|
@@ -26913,7 +27095,7 @@ var Launcher = class {
|
|
|
26913
27095
|
try {
|
|
26914
27096
|
return await this.planOne({ ...req, file }, ctx);
|
|
26915
27097
|
} catch (err) {
|
|
26916
|
-
const code =
|
|
27098
|
+
const code = codeOf8(err);
|
|
26917
27099
|
if (code === "EACCES") denied2 = true;
|
|
26918
27100
|
else if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
|
|
26919
27101
|
}
|
|
@@ -26923,7 +27105,7 @@ var Launcher = class {
|
|
|
26923
27105
|
}
|
|
26924
27106
|
async planOne(req, { ppid, cred, scope }) {
|
|
26925
27107
|
const refused3 = (err) => {
|
|
26926
|
-
throw
|
|
27108
|
+
throw codeOf8(err) === "EACCES" ? new SpawnError("EACCES") : err;
|
|
26927
27109
|
};
|
|
26928
27110
|
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused3);
|
|
26929
27111
|
const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0);
|
|
@@ -28251,6 +28433,21 @@ var Launcher = class {
|
|
|
28251
28433
|
this.writers ??= this.writerStack();
|
|
28252
28434
|
return this.writers;
|
|
28253
28435
|
}
|
|
28436
|
+
flushingPeers(fs) {
|
|
28437
|
+
const peers = fs.peers?.();
|
|
28438
|
+
if (!peers) return void 0;
|
|
28439
|
+
peers.watch((crowded) => {
|
|
28440
|
+
this.changes.flush();
|
|
28441
|
+
this.changes.foreign(crowded);
|
|
28442
|
+
});
|
|
28443
|
+
return {
|
|
28444
|
+
...peers,
|
|
28445
|
+
fresh: () => {
|
|
28446
|
+
this.changes.flush();
|
|
28447
|
+
peers.fresh?.();
|
|
28448
|
+
}
|
|
28449
|
+
};
|
|
28450
|
+
}
|
|
28254
28451
|
rewritten(paths) {
|
|
28255
28452
|
for (const nodes of this.openFiles) for (const path of paths) nodes.rewritten(path);
|
|
28256
28453
|
this.changes.publish(...paths);
|
|
@@ -28433,7 +28630,7 @@ var Launcher = class {
|
|
|
28433
28630
|
function cronLocks() {
|
|
28434
28631
|
return globalThis.navigator?.locks;
|
|
28435
28632
|
}
|
|
28436
|
-
function
|
|
28633
|
+
function codeOf8(err) {
|
|
28437
28634
|
return err?.code;
|
|
28438
28635
|
}
|
|
28439
28636
|
|
|
@@ -28473,14 +28670,14 @@ function clipboardAsker(port) {
|
|
|
28473
28670
|
await ask("write", stamp, text);
|
|
28474
28671
|
}
|
|
28475
28672
|
};
|
|
28476
|
-
const
|
|
28673
|
+
const answer2 = ({ id: id2, text, error }) => {
|
|
28477
28674
|
const waiting = asks.get(id2);
|
|
28478
28675
|
if (!waiting) return;
|
|
28479
28676
|
asks.delete(id2);
|
|
28480
28677
|
if (error) waiting.reject(Object.assign(new Error(error.message), { name: error.name }));
|
|
28481
28678
|
else waiting.resolve(text);
|
|
28482
28679
|
};
|
|
28483
|
-
return { hook, answer };
|
|
28680
|
+
return { hook, answer: answer2 };
|
|
28484
28681
|
}
|
|
28485
28682
|
|
|
28486
28683
|
// src/integrity-relay.ts
|
|
@@ -28494,14 +28691,14 @@ function integrityAsker(port) {
|
|
|
28494
28691
|
port.postMessage({ integrityAsk: { id: id2, path } });
|
|
28495
28692
|
return waiting.promise;
|
|
28496
28693
|
};
|
|
28497
|
-
const
|
|
28694
|
+
const answer2 = ({ id: id2, hash, error }) => {
|
|
28498
28695
|
const waiting = asks.get(id2);
|
|
28499
28696
|
if (!waiting) return;
|
|
28500
28697
|
asks.delete(id2);
|
|
28501
28698
|
if (error !== void 0) waiting.reject(new Error(error));
|
|
28502
28699
|
else waiting.resolve(hash);
|
|
28503
28700
|
};
|
|
28504
|
-
return { lookup: lookup2, answer };
|
|
28701
|
+
return { lookup: lookup2, answer: answer2 };
|
|
28505
28702
|
}
|
|
28506
28703
|
|
|
28507
28704
|
// src/kernel/net/remote-transport.ts
|
|
@@ -28725,14 +28922,14 @@ function sealedAsker(port) {
|
|
|
28725
28922
|
port.postMessage({ sealedAsk: { id: id2, req } });
|
|
28726
28923
|
return waiting.promise.finally(() => signal.removeEventListener("abort", abort));
|
|
28727
28924
|
};
|
|
28728
|
-
const
|
|
28925
|
+
const answer2 = ({ id: id2, reply, error }) => {
|
|
28729
28926
|
const waiting = asks.get(id2);
|
|
28730
28927
|
if (!waiting) return;
|
|
28731
28928
|
asks.delete(id2);
|
|
28732
28929
|
if (reply) waiting.resolve(reply);
|
|
28733
28930
|
else waiting.reject(new Error(error ?? "no reply"));
|
|
28734
28931
|
};
|
|
28735
|
-
return { hook, answer };
|
|
28932
|
+
return { hook, answer: answer2 };
|
|
28736
28933
|
}
|
|
28737
28934
|
|
|
28738
28935
|
// src/serve.ts
|
|
@@ -28845,8 +29042,8 @@ function sudoApprovals(port) {
|
|
|
28845
29042
|
);
|
|
28846
29043
|
port.postMessage({ sudoAsk: req });
|
|
28847
29044
|
}),
|
|
28848
|
-
answer({ id: id2, answer }) {
|
|
28849
|
-
waiting.get(id2)?.(
|
|
29045
|
+
answer({ id: id2, answer: answer2 }) {
|
|
29046
|
+
waiting.get(id2)?.(answer2);
|
|
28850
29047
|
waiting.delete(id2);
|
|
28851
29048
|
}
|
|
28852
29049
|
};
|
|
@@ -28940,10 +29137,10 @@ function policyAsker(port) {
|
|
|
28940
29137
|
return {
|
|
28941
29138
|
mountPolicy: (policy) => policy === void 0 ? {} : { processMounts: policy === "ask" ? askPolicy : policy },
|
|
28942
29139
|
allowed(data) {
|
|
28943
|
-
const
|
|
28944
|
-
if (!
|
|
28945
|
-
policies.get(
|
|
28946
|
-
policies.delete(
|
|
29140
|
+
const answer2 = data.mountAllowed;
|
|
29141
|
+
if (!answer2) return false;
|
|
29142
|
+
policies.get(answer2.id)?.(answer2.allowed);
|
|
29143
|
+
policies.delete(answer2.id);
|
|
28947
29144
|
return true;
|
|
28948
29145
|
}
|
|
28949
29146
|
};
|