@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/node.js
CHANGED
|
@@ -3913,8 +3913,8 @@ var Integrity = class {
|
|
|
3913
3913
|
}
|
|
3914
3914
|
}
|
|
3915
3915
|
async expected(path) {
|
|
3916
|
-
const
|
|
3917
|
-
return typeof
|
|
3916
|
+
const answer2 = await this.lookup(path);
|
|
3917
|
+
return typeof answer2 === "string" ? answer2.toLowerCase() : void 0;
|
|
3918
3918
|
}
|
|
3919
3919
|
say(event) {
|
|
3920
3920
|
try {
|
|
@@ -4154,10 +4154,12 @@ var RemoteWatch = class {
|
|
|
4154
4154
|
quiet;
|
|
4155
4155
|
crowd;
|
|
4156
4156
|
told;
|
|
4157
|
+
counted = 0;
|
|
4157
4158
|
recount() {
|
|
4158
4159
|
const now = this.crowded();
|
|
4159
|
-
if (now === this.told) return;
|
|
4160
|
+
if (now === this.told && this.peers.size === this.counted) return;
|
|
4160
4161
|
this.told = now;
|
|
4162
|
+
this.counted = this.peers.size;
|
|
4161
4163
|
this.crowd?.(now);
|
|
4162
4164
|
}
|
|
4163
4165
|
constructor(name2, options = {}) {
|
|
@@ -4247,12 +4249,12 @@ var RemoteWatch = class {
|
|
|
4247
4249
|
}
|
|
4248
4250
|
greeted(peer) {
|
|
4249
4251
|
this.arrived(peer);
|
|
4250
|
-
const
|
|
4252
|
+
const answer2 = () => {
|
|
4251
4253
|
this.channel.postMessage({ here: this.tab, to: peer });
|
|
4252
4254
|
if (this.mine.length > 0) void this.announce(this.mine);
|
|
4253
4255
|
};
|
|
4254
|
-
if (this.quiet) void this.quiet().then(
|
|
4255
|
-
else
|
|
4256
|
+
if (this.quiet) void this.quiet().then(answer2, answer2);
|
|
4257
|
+
else answer2();
|
|
4256
4258
|
}
|
|
4257
4259
|
announced({ tab, paths, seq: seq2 }) {
|
|
4258
4260
|
const from = tab;
|
|
@@ -7392,7 +7394,7 @@ function satisfies(version, range2) {
|
|
|
7392
7394
|
}
|
|
7393
7395
|
|
|
7394
7396
|
// src/version.ts
|
|
7395
|
-
var KERNEL_VERSION = true ? "1.
|
|
7397
|
+
var KERNEL_VERSION = true ? "1.130.1" : "0.0.0-dev";
|
|
7396
7398
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7397
7399
|
function procVersion() {
|
|
7398
7400
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9427,6 +9429,9 @@ var FileChanges = class {
|
|
|
9427
9429
|
foreign(on) {
|
|
9428
9430
|
Atomics.store(this.view, FOREIGN, on ? 1 : 0);
|
|
9429
9431
|
}
|
|
9432
|
+
flush() {
|
|
9433
|
+
Atomics.add(this.view, GEN, RING_SIZE + 1);
|
|
9434
|
+
}
|
|
9430
9435
|
publish(...paths) {
|
|
9431
9436
|
for (const path of paths) {
|
|
9432
9437
|
const g = Atomics.add(this.view, GEN, 1) + 1 | 0;
|
|
@@ -16301,11 +16306,11 @@ function carriesUdp(uplink) {
|
|
|
16301
16306
|
return uplink.traits.udp === true && typeof uplink.udp === "function";
|
|
16302
16307
|
}
|
|
16303
16308
|
function answerOf(result) {
|
|
16304
|
-
const
|
|
16305
|
-
const addresses = Array.isArray(
|
|
16309
|
+
const answer2 = Array.isArray(result) ? { addresses: result } : result;
|
|
16310
|
+
const addresses = Array.isArray(answer2?.addresses) ? answer2.addresses.filter((a) => typeof a === "string") : [];
|
|
16306
16311
|
return {
|
|
16307
16312
|
addresses,
|
|
16308
|
-
...typeof
|
|
16313
|
+
...typeof answer2?.ttl === "number" && answer2.ttl >= 0 ? { ttl: answer2.ttl } : {}
|
|
16309
16314
|
};
|
|
16310
16315
|
}
|
|
16311
16316
|
var NEVER = new Routes(true);
|
|
@@ -16383,9 +16388,9 @@ var Resolver = class {
|
|
|
16383
16388
|
async lookup(name2, family, id2, abandoned) {
|
|
16384
16389
|
const uplink = this.uplink;
|
|
16385
16390
|
const timeout = AbortSignal.any([AbortSignal.timeout(this.timeoutMs), abandoned]);
|
|
16386
|
-
let
|
|
16391
|
+
let answer2;
|
|
16387
16392
|
try {
|
|
16388
|
-
|
|
16393
|
+
answer2 = answerOf(
|
|
16389
16394
|
await Promise.race([
|
|
16390
16395
|
uplink.resolve(name2, family, timeout),
|
|
16391
16396
|
new Promise(
|
|
@@ -16396,8 +16401,8 @@ var Resolver = class {
|
|
|
16396
16401
|
} catch {
|
|
16397
16402
|
return [];
|
|
16398
16403
|
}
|
|
16399
|
-
const addresses =
|
|
16400
|
-
if (addresses.length > 0) this.remember(id2, addresses,
|
|
16404
|
+
const addresses = answer2.addresses.filter((a) => this.usable(name2, a, family));
|
|
16405
|
+
if (addresses.length > 0) this.remember(id2, addresses, answer2.ttl);
|
|
16401
16406
|
return addresses;
|
|
16402
16407
|
}
|
|
16403
16408
|
usable(name2, address, family) {
|
|
@@ -21053,8 +21058,8 @@ var WasmProcess = class {
|
|
|
21053
21058
|
spares(sig) {
|
|
21054
21059
|
const { caught, ignored } = this.signalMasks();
|
|
21055
21060
|
const bit = isSignal(sig) ? sigbit(sig) : 0;
|
|
21056
|
-
const
|
|
21057
|
-
return { ok: true, kind: "json", json:
|
|
21061
|
+
const answer2 = (ignored & bit) !== 0 ? "ignore" : (caught & bit) !== 0 ? "spare" : "terminate";
|
|
21062
|
+
return { ok: true, kind: "json", json: answer2 };
|
|
21058
21063
|
}
|
|
21059
21064
|
async killSelf(sig, target, probe2) {
|
|
21060
21065
|
if (!this.options.exitSignal) throw new KernelError("ENOSYS");
|
|
@@ -22171,10 +22176,10 @@ var WasmProcess = class {
|
|
|
22171
22176
|
cwd: typeof req.cwd === "string" && req.cwd.startsWith("/") ? req.cwd : "/",
|
|
22172
22177
|
...typeof req.term === "string" ? { term: req.term } : {}
|
|
22173
22178
|
};
|
|
22174
|
-
const
|
|
22175
|
-
if (!("grant" in
|
|
22179
|
+
const answer2 = await sudo(call, this.blockingSignal(cancelled));
|
|
22180
|
+
if (!("grant" in answer2)) return answer2;
|
|
22176
22181
|
if (this.dying) throw new KernelError("EINTR");
|
|
22177
|
-
const { file, argv, env, cwd, cred, caller } =
|
|
22182
|
+
const { file, argv, env, cwd, cred, caller } = answer2.grant;
|
|
22178
22183
|
const stdio = [{ fd: 0 }, { fd: 1 }, { fd: 2 }];
|
|
22179
22184
|
return {
|
|
22180
22185
|
pid: await this.children.spawn({ file, argv, env, cwd, pgid: 0 }, stdio, [], {
|
|
@@ -22334,6 +22339,153 @@ var WASM_THREAD_SPAWN = "wasm-thread-spawn";
|
|
|
22334
22339
|
var WASM_THREAD_INIT = "wasm-thread-init";
|
|
22335
22340
|
var WASM_THREAD_EXIT = "wasm-thread-exit";
|
|
22336
22341
|
var WASM_MAX_THREADS = 256;
|
|
22342
|
+
var JS_THREAD_SPAWN = "js-thread-spawn";
|
|
22343
|
+
var JS_THREAD_INIT = "js-thread-init";
|
|
22344
|
+
var JS_THREAD_EXIT = "js-thread-exit";
|
|
22345
|
+
var JS_MAX_THREADS = 256;
|
|
22346
|
+
var JS_DEFAULT_THREADS = 16;
|
|
22347
|
+
var JS_THREAD_NO_MEMORY = 256;
|
|
22348
|
+
var JS_THREAD_CRASHED = 257;
|
|
22349
|
+
|
|
22350
|
+
// src/kernel/js-threads.ts
|
|
22351
|
+
var JS_OOM = /out of memory|Array buffer allocation failed|Cannot allocate Wasm memory|could not allocate memory|ERR_WORKER_OUT_OF_MEMORY/i;
|
|
22352
|
+
var ENDING = { ok: false, errno: "EINTR", message: "the thread is ending" };
|
|
22353
|
+
var MAIN_ONLY = { ok: true, kind: "void" };
|
|
22354
|
+
function track(ops, req, result) {
|
|
22355
|
+
if (req.op === "async-submit" && result.ok && result.kind === "json") {
|
|
22356
|
+
if (typeof result.json === "number") ops.set(result.json, req.token);
|
|
22357
|
+
} else if (req.op === "async-cancel" || req.op === "async-take" && (result.ok || result.errno !== "EAGAIN")) {
|
|
22358
|
+
ops.delete(req.id);
|
|
22359
|
+
}
|
|
22360
|
+
}
|
|
22361
|
+
function cores() {
|
|
22362
|
+
const n = globalThis.navigator?.hardwareConcurrency;
|
|
22363
|
+
return typeof n === "number" && Number.isInteger(n) && n > 0 ? n : 0;
|
|
22364
|
+
}
|
|
22365
|
+
function jsThreadCap(env) {
|
|
22366
|
+
const asked = Number.parseInt(env.SLICC_JS_THREADS ?? "", 10);
|
|
22367
|
+
if (asked >= 1) return Math.min(asked, JS_MAX_THREADS);
|
|
22368
|
+
return Math.min(JS_MAX_THREADS, Math.max(JS_DEFAULT_THREADS, 2 * cores()));
|
|
22369
|
+
}
|
|
22370
|
+
function codeOf4(code) {
|
|
22371
|
+
if (code === JS_THREAD_NO_MEMORY || code === JS_THREAD_CRASHED) return code;
|
|
22372
|
+
return typeof code === "number" && Number.isInteger(code) ? code & 255 : JS_THREAD_CRASHED;
|
|
22373
|
+
}
|
|
22374
|
+
function answer(control, message3) {
|
|
22375
|
+
control.postMessage(message3);
|
|
22376
|
+
}
|
|
22377
|
+
var JsThreads = class {
|
|
22378
|
+
deps;
|
|
22379
|
+
live = /* @__PURE__ */ new Map();
|
|
22380
|
+
headers = /* @__PURE__ */ new Map();
|
|
22381
|
+
frozen = false;
|
|
22382
|
+
last = 0;
|
|
22383
|
+
closed = false;
|
|
22384
|
+
constructor(deps) {
|
|
22385
|
+
this.deps = deps;
|
|
22386
|
+
}
|
|
22387
|
+
get size() {
|
|
22388
|
+
return this.live.size;
|
|
22389
|
+
}
|
|
22390
|
+
spawn(msg) {
|
|
22391
|
+
const { control, port } = msg;
|
|
22392
|
+
if (this.closed || this.live.size >= this.deps.cap) {
|
|
22393
|
+
answer(
|
|
22394
|
+
control,
|
|
22395
|
+
this.closed ? { errno: "ESRCH", message: "the process is ending" } : { errno: "EAGAIN", message: `more than ${this.deps.cap} threads` }
|
|
22396
|
+
);
|
|
22397
|
+
control.close();
|
|
22398
|
+
port.close();
|
|
22399
|
+
return;
|
|
22400
|
+
}
|
|
22401
|
+
const tid = ++this.last;
|
|
22402
|
+
const sab = new SharedArrayBuffer(SAB_HEADER_BYTES + SAB_DEFAULT_WINDOW_BYTES);
|
|
22403
|
+
const header4 = new Int32Array(sab, 0, SAB_HEADER_I32);
|
|
22404
|
+
if (this.frozen) Atomics.store(header4, SAB_I_STOP, 1);
|
|
22405
|
+
const worker = this.deps.createWorker();
|
|
22406
|
+
const clock = this.deps.clocks.thread(tid + 1, sab);
|
|
22407
|
+
let ended = false;
|
|
22408
|
+
const end = (code) => {
|
|
22409
|
+
if (ended) return;
|
|
22410
|
+
ended = true;
|
|
22411
|
+
this.live.delete(tid);
|
|
22412
|
+
this.headers.delete(tid);
|
|
22413
|
+
this.deps.wakes.delete(header4);
|
|
22414
|
+
for (const [id2, token] of ops) {
|
|
22415
|
+
void this.deps.dispatch({ op: "async-cancel", id: id2, token });
|
|
22416
|
+
}
|
|
22417
|
+
ops.clear();
|
|
22418
|
+
worker.removeEventListener("message", onMessage);
|
|
22419
|
+
worker.removeEventListener("error", onError);
|
|
22420
|
+
control.removeEventListener("message", onControl);
|
|
22421
|
+
responder.dispose();
|
|
22422
|
+
lane.dispose();
|
|
22423
|
+
this.deps.clocks.threadEnded(tid + 1);
|
|
22424
|
+
worker.terminate();
|
|
22425
|
+
answer(control, { exited: code });
|
|
22426
|
+
control.close();
|
|
22427
|
+
};
|
|
22428
|
+
const ops = /* @__PURE__ */ new Map();
|
|
22429
|
+
const dispatch2 = async (req, block) => {
|
|
22430
|
+
if (isWasmSyscall(req) && req.op === "proc-exit") {
|
|
22431
|
+
queueMicrotask(() => end(req.status & 255));
|
|
22432
|
+
return ENDING;
|
|
22433
|
+
}
|
|
22434
|
+
if (isWasmSyscall(req) && req.op === "sig-mask") return MAIN_ONLY;
|
|
22435
|
+
const result = await this.deps.dispatch(req, block);
|
|
22436
|
+
if (!ended) track(ops, req, result);
|
|
22437
|
+
return result;
|
|
22438
|
+
};
|
|
22439
|
+
const responder = this.deps.attach(worker, sab, this.deps.clocks.timed(clock, dispatch2));
|
|
22440
|
+
const lane = this.deps.openLane(dispatch2);
|
|
22441
|
+
const onMessage = (event) => {
|
|
22442
|
+
const data = event.data;
|
|
22443
|
+
if (data?.type === JS_THREAD_EXIT) end(codeOf4(data.code));
|
|
22444
|
+
else if (data?.type === JS_THREAD_SPAWN) this.spawn(event.data);
|
|
22445
|
+
else if (data?.type === WASM_PROCESS_ERROR) this.crashed(String(data.message), end);
|
|
22446
|
+
};
|
|
22447
|
+
const onError = (event) => {
|
|
22448
|
+
event.preventDefault();
|
|
22449
|
+
this.crashed(String(event.message ?? "worker error"), end);
|
|
22450
|
+
};
|
|
22451
|
+
const onControl = (event) => {
|
|
22452
|
+
if (event.data?.terminate === true) end(1);
|
|
22453
|
+
};
|
|
22454
|
+
worker.addEventListener("message", onMessage);
|
|
22455
|
+
worker.addEventListener("error", onError);
|
|
22456
|
+
control.addEventListener("message", onControl);
|
|
22457
|
+
control.start();
|
|
22458
|
+
this.live.set(tid, end);
|
|
22459
|
+
this.headers.set(tid, header4);
|
|
22460
|
+
this.deps.wakes.add(header4);
|
|
22461
|
+
const init = {
|
|
22462
|
+
...this.deps.init(sab, lane.lane),
|
|
22463
|
+
type: JS_THREAD_INIT,
|
|
22464
|
+
thread: { tid, port, data: msg.data }
|
|
22465
|
+
};
|
|
22466
|
+
try {
|
|
22467
|
+
worker.postMessage(init, [lane.lane.port, port, ...msg.transfer ?? []]);
|
|
22468
|
+
} catch {
|
|
22469
|
+
end(JS_THREAD_CRASHED);
|
|
22470
|
+
return;
|
|
22471
|
+
}
|
|
22472
|
+
answer(control, { tid });
|
|
22473
|
+
}
|
|
22474
|
+
crashed(message3, end) {
|
|
22475
|
+
end(JS_OOM.test(message3) ? JS_THREAD_NO_MEMORY : JS_THREAD_CRASHED);
|
|
22476
|
+
}
|
|
22477
|
+
stopped(stopped) {
|
|
22478
|
+
this.frozen = stopped;
|
|
22479
|
+
for (const header4 of this.headers.values()) {
|
|
22480
|
+
Atomics.store(header4, SAB_I_STOP, stopped ? 1 : 0);
|
|
22481
|
+
Atomics.notify(header4, SAB_I_STOP);
|
|
22482
|
+
}
|
|
22483
|
+
}
|
|
22484
|
+
close() {
|
|
22485
|
+
this.closed = true;
|
|
22486
|
+
for (const end of [...this.live.values()]) end(1);
|
|
22487
|
+
}
|
|
22488
|
+
};
|
|
22337
22489
|
|
|
22338
22490
|
// src/kernel/host.ts
|
|
22339
22491
|
var CRASHED = 70;
|
|
@@ -22436,6 +22588,7 @@ function threadSignalsOf(sab) {
|
|
|
22436
22588
|
function threadCancel(thread) {
|
|
22437
22589
|
return unblocked(thread.header) !== 0 ? AbortSignal.abort() : thread.interrupt.signal;
|
|
22438
22590
|
}
|
|
22591
|
+
var asyncFanout = /* @__PURE__ */ new WeakMap();
|
|
22439
22592
|
function notifiers(header4) {
|
|
22440
22593
|
return {
|
|
22441
22594
|
onPending(sig) {
|
|
@@ -22443,8 +22596,10 @@ function notifiers(header4) {
|
|
|
22443
22596
|
Atomics.notify(header4, SAB_I_SIGNALS);
|
|
22444
22597
|
},
|
|
22445
22598
|
onAsync() {
|
|
22446
|
-
|
|
22447
|
-
|
|
22599
|
+
for (const at of [header4, ...asyncFanout.get(header4) ?? []]) {
|
|
22600
|
+
Atomics.add(at, SAB_I_ASYNC, 1);
|
|
22601
|
+
Atomics.notify(at, SAB_I_ASYNC);
|
|
22602
|
+
}
|
|
22448
22603
|
}
|
|
22449
22604
|
};
|
|
22450
22605
|
}
|
|
@@ -22675,6 +22830,7 @@ function spawnWasmProcess(opts) {
|
|
|
22675
22830
|
dispatch: clocks.timed(void 0, dispatch2)
|
|
22676
22831
|
});
|
|
22677
22832
|
const lane = opts.program.abi === "js" ? openLane(token, dispatch2) : void 0;
|
|
22833
|
+
const jsThreads = jsThreadsOf(opts, process2, token, dispatch2, clocks, header4);
|
|
22678
22834
|
const { promise: exited, resolve: settle } = Promise.withResolvers();
|
|
22679
22835
|
let done4 = false;
|
|
22680
22836
|
let endedBy;
|
|
@@ -22688,6 +22844,7 @@ function spawnWasmProcess(opts) {
|
|
|
22688
22844
|
worker.removeEventListener("message", onMessage);
|
|
22689
22845
|
worker.removeEventListener("error", onError);
|
|
22690
22846
|
for (const tid of [...threads.keys()]) endThread(tid);
|
|
22847
|
+
jsThreads?.close();
|
|
22691
22848
|
responder.dispose();
|
|
22692
22849
|
lane?.dispose();
|
|
22693
22850
|
revokeSyncFsToken(token);
|
|
@@ -22711,6 +22868,8 @@ function spawnWasmProcess(opts) {
|
|
|
22711
22868
|
finish(...dying.status(data.code));
|
|
22712
22869
|
} else if (data?.type === WASM_THREAD_SPAWN && data.thread) {
|
|
22713
22870
|
spawnThread(data.thread);
|
|
22871
|
+
} else if (data?.type === JS_THREAD_SPAWN && jsThreads) {
|
|
22872
|
+
jsThreads.spawn(data);
|
|
22714
22873
|
}
|
|
22715
22874
|
};
|
|
22716
22875
|
const onMessage = (event) => handle(event.data);
|
|
@@ -22784,13 +22943,35 @@ function spawnWasmProcess(opts) {
|
|
|
22784
22943
|
termsig: () => endedBy,
|
|
22785
22944
|
onState: (listener) => process2.onState(listener),
|
|
22786
22945
|
memory: () => Atomics.load(header4, SAB_I_MEMORY) * 65536,
|
|
22946
|
+
...processViews(process2, opts, header4),
|
|
22947
|
+
writesBack: () => opts.program.abi === "wasi" && !done4,
|
|
22948
|
+
...clockViews(clocks)
|
|
22949
|
+
};
|
|
22950
|
+
}
|
|
22951
|
+
function jsThreadsOf(opts, process2, token, dispatch2, clocks, header4) {
|
|
22952
|
+
if (opts.program.abi !== "js") return void 0;
|
|
22953
|
+
const wakes = /* @__PURE__ */ new Set();
|
|
22954
|
+
asyncFanout.set(header4, wakes);
|
|
22955
|
+
const threads = new JsThreads({
|
|
22956
|
+
wakes,
|
|
22957
|
+
cap: jsThreadCap(opts.env),
|
|
22958
|
+
createWorker: opts.createWorker,
|
|
22959
|
+
init: (sab, lane) => processInit(opts, sab, process2.umask, copyCred(process2.cred), lane),
|
|
22960
|
+
openLane: (laneDispatch) => openLane(token, laneDispatch),
|
|
22961
|
+
attach: (worker, sab, threadDispatch) => attachSyncSabResponder(worker, sab, token, { dispatch: threadDispatch }),
|
|
22962
|
+
dispatch: dispatch2,
|
|
22963
|
+
clocks
|
|
22964
|
+
});
|
|
22965
|
+
process2.onState((state) => threads.stopped(state === "stopped"));
|
|
22966
|
+
return threads;
|
|
22967
|
+
}
|
|
22968
|
+
function processViews(process2, opts, header4) {
|
|
22969
|
+
return {
|
|
22787
22970
|
ignoredSignals: (fork) => process2.inheritable(fork),
|
|
22788
22971
|
blockedSignals: () => opts.program.abi === "wasi" ? loadBlocked(header4) : [0, 0],
|
|
22789
22972
|
signalMasks: () => process2.signalMasks(),
|
|
22790
22973
|
umask: () => process2.umask,
|
|
22791
|
-
cred: () => copyCred(process2.cred)
|
|
22792
|
-
writesBack: () => opts.program.abi === "wasi" && !done4,
|
|
22793
|
-
...clockViews(clocks)
|
|
22974
|
+
cred: () => copyCred(process2.cred)
|
|
22794
22975
|
};
|
|
22795
22976
|
}
|
|
22796
22977
|
function clockViews(clocks) {
|
|
@@ -24108,8 +24289,8 @@ var FSA_CAPABILITIES = {
|
|
|
24108
24289
|
ranges: true,
|
|
24109
24290
|
sessions: true
|
|
24110
24291
|
};
|
|
24111
|
-
var
|
|
24112
|
-
var denied = (err) =>
|
|
24292
|
+
var codeOf5 = (err) => err?.code;
|
|
24293
|
+
var denied = (err) => codeOf5(err) === "EACCES" || err?.name === "NotAllowedError";
|
|
24113
24294
|
function attrOf(st) {
|
|
24114
24295
|
return {
|
|
24115
24296
|
kind: st.isDirectory ? "directory" : st.isSymbolicLink ? "symlink" : "file",
|
|
@@ -24131,7 +24312,7 @@ function kernelFsHandlers(fs) {
|
|
|
24131
24312
|
try {
|
|
24132
24313
|
return await fs.stat(path);
|
|
24133
24314
|
} catch (err) {
|
|
24134
|
-
if (
|
|
24315
|
+
if (codeOf5(err) === "ENOENT") return void 0;
|
|
24135
24316
|
throw err;
|
|
24136
24317
|
}
|
|
24137
24318
|
}
|
|
@@ -24324,7 +24505,7 @@ function parseFstab(text) {
|
|
|
24324
24505
|
});
|
|
24325
24506
|
return lines2;
|
|
24326
24507
|
}
|
|
24327
|
-
function
|
|
24508
|
+
function codeOf6(err) {
|
|
24328
24509
|
const code = err?.code;
|
|
24329
24510
|
return typeof code === "string" ? code : "EIO";
|
|
24330
24511
|
}
|
|
@@ -24362,18 +24543,18 @@ async function mountLine({ line, spec, invalid }, mount, signal, retries, discar
|
|
|
24362
24543
|
break;
|
|
24363
24544
|
} catch (err) {
|
|
24364
24545
|
failed3 = err;
|
|
24365
|
-
if (FINAL.has(
|
|
24546
|
+
if (FINAL.has(codeOf6(err)) || attempt === retries.length) break;
|
|
24366
24547
|
await wait(retries[attempt], signal);
|
|
24367
24548
|
}
|
|
24368
24549
|
}
|
|
24369
|
-
const code =
|
|
24550
|
+
const code = codeOf6(failed3);
|
|
24370
24551
|
return { line, target: spec.target, code, error: String(failed3?.message ?? code) };
|
|
24371
24552
|
}
|
|
24372
24553
|
|
|
24373
24554
|
// src/mount/hostfs.ts
|
|
24374
24555
|
var HOSTFS_IO = 16 * 1024 * 1024;
|
|
24375
|
-
var
|
|
24376
|
-
var unreachable = (err) =>
|
|
24556
|
+
var codeOf7 = (err) => err?.code;
|
|
24557
|
+
var unreachable = (err) => codeOf7(err) === "ENOTCONN";
|
|
24377
24558
|
function rel(path) {
|
|
24378
24559
|
return path.replace(/^\/+/, "");
|
|
24379
24560
|
}
|
|
@@ -24550,7 +24731,7 @@ function hostfsHandlers(current, againMs = RESTORE_AGAIN_MS) {
|
|
|
24550
24731
|
try {
|
|
24551
24732
|
return { opened: await opening2(), restore: void 0 };
|
|
24552
24733
|
} catch (err) {
|
|
24553
|
-
if (!flags2.write ||
|
|
24734
|
+
if (!flags2.write || codeOf7(err) !== "EACCES") throw err;
|
|
24554
24735
|
const was = await client.call("stat", { path: rel(path) });
|
|
24555
24736
|
const mode = was.mode ?? 0;
|
|
24556
24737
|
if (mode & 128) throw err;
|
|
@@ -24975,7 +25156,7 @@ var PortTransport = class {
|
|
|
24975
25156
|
}
|
|
24976
25157
|
};
|
|
24977
25158
|
var errorOf = (err) => ({
|
|
24978
|
-
code: typeof
|
|
25159
|
+
code: typeof codeOf7(err) === "string" ? codeOf7(err) : "EIO",
|
|
24979
25160
|
message: err?.message ?? String(err)
|
|
24980
25161
|
});
|
|
24981
25162
|
function serveHostfsPort(port, transport) {
|
|
@@ -24989,14 +25170,14 @@ function serveHostfsPort(port, transport) {
|
|
|
24989
25170
|
};
|
|
24990
25171
|
const send2 = (reply, transfer = []) => port.postMessage(reply, transfer);
|
|
24991
25172
|
const pending = /* @__PURE__ */ new Set();
|
|
24992
|
-
const
|
|
25173
|
+
const track2 = (work) => {
|
|
24993
25174
|
pending.add(work);
|
|
24994
25175
|
const done4 = () => pending.delete(work);
|
|
24995
25176
|
work.then(done4, done4);
|
|
24996
25177
|
return work;
|
|
24997
25178
|
};
|
|
24998
|
-
const
|
|
24999
|
-
const result = await
|
|
25179
|
+
const answer2 = async (name2, body) => {
|
|
25180
|
+
const result = await track2(transport.call(name2, body));
|
|
25000
25181
|
const opened2 = result?.fh;
|
|
25001
25182
|
if (name2 === "open" && typeof opened2 === "number") handles.add(opened2);
|
|
25002
25183
|
if (name2 === "release") handles.delete(body?.fh);
|
|
@@ -25010,7 +25191,7 @@ function serveHostfsPort(port, transport) {
|
|
|
25010
25191
|
if (op === "ping") return send2({ id: id2, pong: true });
|
|
25011
25192
|
if (op === "bye") return stop();
|
|
25012
25193
|
if (op === "cleanup")
|
|
25013
|
-
return void Promise.allSettled([...pending]).then(() =>
|
|
25194
|
+
return void Promise.allSettled([...pending]).then(() => answer2(data.name, data.body)).catch(() => {
|
|
25014
25195
|
});
|
|
25015
25196
|
if (op === "unwatch") return watches.get(id2)?.abort();
|
|
25016
25197
|
if (op === "watch") {
|
|
@@ -25032,7 +25213,7 @@ function serveHostfsPort(port, transport) {
|
|
|
25032
25213
|
}
|
|
25033
25214
|
try {
|
|
25034
25215
|
if (op === "read") {
|
|
25035
|
-
const read = await
|
|
25216
|
+
const read = await track2(
|
|
25036
25217
|
transport.read(
|
|
25037
25218
|
data.fh,
|
|
25038
25219
|
data.offset,
|
|
@@ -25044,13 +25225,13 @@ function serveHostfsPort(port, transport) {
|
|
|
25044
25225
|
return send2({ id: id2, bytes }, [bytes.buffer]);
|
|
25045
25226
|
}
|
|
25046
25227
|
if (op === "write") {
|
|
25047
|
-
await
|
|
25228
|
+
await track2(
|
|
25048
25229
|
transport.write(data.fh, data.offset, data.bytes)
|
|
25049
25230
|
);
|
|
25050
25231
|
return send2({ id: id2 });
|
|
25051
25232
|
}
|
|
25052
25233
|
if (op !== "call") throw fsError2("EINVAL", `unknown hostfs port op ${op}`);
|
|
25053
|
-
send2({ id: id2, result: await
|
|
25234
|
+
send2({ id: id2, result: await answer2(data.name, data.body) });
|
|
25054
25235
|
} catch (err) {
|
|
25055
25236
|
send2({ id: id2, error: errorOf(err) });
|
|
25056
25237
|
}
|
|
@@ -25842,14 +26023,14 @@ var Sudo = class {
|
|
|
25842
26023
|
if (this.pending.has(cred.ruid)) return failed2("EBUSY", "sudo: another request is pending");
|
|
25843
26024
|
this.pending.add(cred.ruid);
|
|
25844
26025
|
try {
|
|
25845
|
-
const
|
|
25846
|
-
if (typeof
|
|
26026
|
+
const answer2 = await this.ask(caller, self, target, parsed2.command, path, cwd, signal);
|
|
26027
|
+
if (typeof answer2 !== "string") return answer2;
|
|
25847
26028
|
if (await this.canonical(call.cwd) !== cwd || !await this.reachable(cred, cwd)) {
|
|
25848
26029
|
return failed2("EACCES", `sudo: ${call.cwd} changed while the request waited`);
|
|
25849
26030
|
}
|
|
25850
26031
|
const changed = await this.untrusted(path, cwd, word);
|
|
25851
26032
|
if (changed) return changed;
|
|
25852
|
-
if (
|
|
26033
|
+
if (answer2 === "always" && !await this.remember(self, target, cwd, argv)) {
|
|
25853
26034
|
return failed2("EIO", "sudo: the rule could not be recorded");
|
|
25854
26035
|
}
|
|
25855
26036
|
return grant();
|
|
@@ -25904,11 +26085,11 @@ ${lines2}
|
|
|
25904
26085
|
);
|
|
25905
26086
|
try {
|
|
25906
26087
|
const answered = Promise.resolve().then(() => approve(req, { signal: control.signal })).catch(() => "deny");
|
|
25907
|
-
const
|
|
25908
|
-
if (
|
|
26088
|
+
const answer2 = await Promise.race([answered, aborted2]);
|
|
26089
|
+
if (answer2 === "aborted" || control.signal.aborted) {
|
|
25909
26090
|
return control.signal.reason === "expired" ? failed2("ETIMEDOUT", "sudo: the request expired") : failed2("EINTR", "sudo: the request was withdrawn");
|
|
25910
26091
|
}
|
|
25911
|
-
return
|
|
26092
|
+
return answer2 === "once" || answer2 === "always" ? answer2 : failed2("EACCES", "sudo: approval denied");
|
|
25912
26093
|
} finally {
|
|
25913
26094
|
clearTimeout(timer);
|
|
25914
26095
|
requester.removeEventListener("abort", withdraw);
|
|
@@ -26316,9 +26497,7 @@ var Launcher = class {
|
|
|
26316
26497
|
this.usersMode = usersMode(options.users);
|
|
26317
26498
|
this.memories = memoriesOf(options.wasmMemories);
|
|
26318
26499
|
this.rootFs = options.fs;
|
|
26319
|
-
|
|
26320
|
-
this.locks = kernelLocks(options.fs.rootName, peers);
|
|
26321
|
-
peers?.watch((crowded) => this.changes.foreign(crowded));
|
|
26500
|
+
this.locks = kernelLocks(options.fs.rootName, this.flushingPeers(options.fs));
|
|
26322
26501
|
this.dac = this.usersMode === "off" ? void 0 : new Dac(this.usersMode, options.onDenial);
|
|
26323
26502
|
if (this.dac) this.dac.tagOf = (pid) => this.tagOf(pid);
|
|
26324
26503
|
this.clipboard = new ClipboardBroker(
|
|
@@ -26404,7 +26583,10 @@ var Launcher = class {
|
|
|
26404
26583
|
this.nodes.keepsOnDisk = true;
|
|
26405
26584
|
this.openFiles.add(this.nodes);
|
|
26406
26585
|
options.fs.onPeer?.(() => this.flushOpen());
|
|
26407
|
-
options.fs.remoteChanges?.((change) =>
|
|
26586
|
+
options.fs.remoteChanges?.((change) => {
|
|
26587
|
+
this.changes.flush();
|
|
26588
|
+
this.rewritten(change.paths);
|
|
26589
|
+
});
|
|
26408
26590
|
const holders = [this.held, this.openFiles];
|
|
26409
26591
|
this.unlinked = new UnlinkedKeeper(
|
|
26410
26592
|
fs,
|
|
@@ -26819,7 +27001,7 @@ var Launcher = class {
|
|
|
26819
27001
|
try {
|
|
26820
27002
|
return await this.planOne(req, ctx);
|
|
26821
27003
|
} catch (err) {
|
|
26822
|
-
const code =
|
|
27004
|
+
const code = codeOf8(err);
|
|
26823
27005
|
const searched = bare && req.search !== false && (code === "ENOENT" || code === "ENOEXEC");
|
|
26824
27006
|
if (!searched || await this.commandAt(req.file, ctx.scope)) throw err;
|
|
26825
27007
|
const found = await this.onPath(req, ctx);
|
|
@@ -26836,7 +27018,7 @@ var Launcher = class {
|
|
|
26836
27018
|
try {
|
|
26837
27019
|
return await this.planOne({ ...req, file }, ctx);
|
|
26838
27020
|
} catch (err) {
|
|
26839
|
-
const code =
|
|
27021
|
+
const code = codeOf8(err);
|
|
26840
27022
|
if (code === "EACCES") denied2 = true;
|
|
26841
27023
|
else if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
|
|
26842
27024
|
}
|
|
@@ -26846,7 +27028,7 @@ var Launcher = class {
|
|
|
26846
27028
|
}
|
|
26847
27029
|
async planOne(req, { ppid, cred, scope }) {
|
|
26848
27030
|
const refused3 = (err) => {
|
|
26849
|
-
throw
|
|
27031
|
+
throw codeOf8(err) === "EACCES" ? new SpawnError("EACCES") : err;
|
|
26850
27032
|
};
|
|
26851
27033
|
const file = await this.execFile(req.file, req.cwd, this.execGuard(cred, ppid)).catch(refused3);
|
|
26852
27034
|
const planned = await this.plan(file, req.argv, req.cwd, scope, req.argv0);
|
|
@@ -28174,6 +28356,21 @@ var Launcher = class {
|
|
|
28174
28356
|
this.writers ??= this.writerStack();
|
|
28175
28357
|
return this.writers;
|
|
28176
28358
|
}
|
|
28359
|
+
flushingPeers(fs) {
|
|
28360
|
+
const peers = fs.peers?.();
|
|
28361
|
+
if (!peers) return void 0;
|
|
28362
|
+
peers.watch((crowded) => {
|
|
28363
|
+
this.changes.flush();
|
|
28364
|
+
this.changes.foreign(crowded);
|
|
28365
|
+
});
|
|
28366
|
+
return {
|
|
28367
|
+
...peers,
|
|
28368
|
+
fresh: () => {
|
|
28369
|
+
this.changes.flush();
|
|
28370
|
+
peers.fresh?.();
|
|
28371
|
+
}
|
|
28372
|
+
};
|
|
28373
|
+
}
|
|
28177
28374
|
rewritten(paths) {
|
|
28178
28375
|
for (const nodes of this.openFiles) for (const path of paths) nodes.rewritten(path);
|
|
28179
28376
|
this.changes.publish(...paths);
|
|
@@ -28356,7 +28553,7 @@ var Launcher = class {
|
|
|
28356
28553
|
function cronLocks() {
|
|
28357
28554
|
return globalThis.navigator?.locks;
|
|
28358
28555
|
}
|
|
28359
|
-
function
|
|
28556
|
+
function codeOf8(err) {
|
|
28360
28557
|
return err?.code;
|
|
28361
28558
|
}
|
|
28362
28559
|
|
|
@@ -28769,7 +28966,7 @@ import { connect as tls } from "node:tls";
|
|
|
28769
28966
|
var PROBE_MS = 3e3;
|
|
28770
28967
|
var PASSED = /* @__PURE__ */ new Set(["ECONNREFUSED", "EHOSTUNREACH", "ENETUNREACH", "ETIMEDOUT", "ECONNRESET"]);
|
|
28771
28968
|
var NO_NAME = /* @__PURE__ */ new Set(["ENOTFOUND", "EAI_AGAIN", "EAI_NONAME", "EAI_FAIL", "ENODATA"]);
|
|
28772
|
-
function
|
|
28969
|
+
function codeOf9(e) {
|
|
28773
28970
|
const code = e?.code;
|
|
28774
28971
|
return typeof code === "string" ? code : void 0;
|
|
28775
28972
|
}
|
|
@@ -28798,7 +28995,7 @@ function probe(secure2, host, port, ms, signal) {
|
|
|
28798
28995
|
signal?.addEventListener("abort", stop, { once: true });
|
|
28799
28996
|
socket.once(secure2 ? "secureConnect" : "connect", () => done4("EPROTO"));
|
|
28800
28997
|
socket.once("error", (e) => {
|
|
28801
|
-
const code =
|
|
28998
|
+
const code = codeOf9(e) ?? "";
|
|
28802
28999
|
done4(PASSED.has(code) ? code : "EPROTO");
|
|
28803
29000
|
});
|
|
28804
29001
|
});
|
|
@@ -28813,7 +29010,7 @@ async function diagnose(url, ms = PROBE_MS, signal) {
|
|
|
28813
29010
|
await abortable(lookup3(host), signal);
|
|
28814
29011
|
} catch (e) {
|
|
28815
29012
|
if (signal?.aborted) throw signal.reason;
|
|
28816
|
-
return NO_NAME.has(
|
|
29013
|
+
return NO_NAME.has(codeOf9(e) ?? "") ? "EAI_NONAME" : void 0;
|
|
28817
29014
|
}
|
|
28818
29015
|
const code = await probe(secure2, host, port, ms, signal);
|
|
28819
29016
|
signal?.throwIfAborted();
|
|
@@ -28832,7 +29029,7 @@ function diagnosing(transport, check = byDefault) {
|
|
|
28832
29029
|
try {
|
|
28833
29030
|
return await open(request);
|
|
28834
29031
|
} catch (e) {
|
|
28835
|
-
if (request.signal.aborted || !(e instanceof Error) ||
|
|
29032
|
+
if (request.signal.aborted || !(e instanceof Error) || codeOf9(e)) throw e;
|
|
28836
29033
|
const code = await abortable(
|
|
28837
29034
|
check(request.url, request.signal).catch(() => void 0),
|
|
28838
29035
|
request.signal
|