@ai-ecoverse/slicc-kernel 1.64.1 → 1.65.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 +9 -2
- package/dist/driver-worker.js +87 -4
- package/dist/driver-worker.js.map +3 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +183 -39
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +401 -195
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +183 -39
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +492 -270
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -6839,6 +6839,23 @@ var CONTINUED_STATUS = 65535;
|
|
|
6839
6839
|
function waitStatus(code, termsig) {
|
|
6840
6840
|
return termsig ? termsig & 127 : (code & 255) << 8;
|
|
6841
6841
|
}
|
|
6842
|
+
function capturing(chunks, max = Number.POSITIVE_INFINITY, overflow) {
|
|
6843
|
+
let size = 0;
|
|
6844
|
+
let over = false;
|
|
6845
|
+
return (bytes) => {
|
|
6846
|
+
if (over) return;
|
|
6847
|
+
const room = max - size;
|
|
6848
|
+
if (bytes.length > room) {
|
|
6849
|
+
over = true;
|
|
6850
|
+
if (room > 0) chunks.push(bytes.slice(0, room));
|
|
6851
|
+
size = max;
|
|
6852
|
+
overflow?.();
|
|
6853
|
+
return;
|
|
6854
|
+
}
|
|
6855
|
+
chunks.push(bytes);
|
|
6856
|
+
size += bytes.length;
|
|
6857
|
+
};
|
|
6858
|
+
}
|
|
6842
6859
|
function concat3(chunks) {
|
|
6843
6860
|
const out = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));
|
|
6844
6861
|
let offset = 0;
|
|
@@ -6872,15 +6889,15 @@ var ChildTable = class {
|
|
|
6872
6889
|
const fds = new FdTable();
|
|
6873
6890
|
const captured = /* @__PURE__ */ new Map();
|
|
6874
6891
|
try {
|
|
6875
|
-
for (const [n,
|
|
6876
|
-
for (const
|
|
6877
|
-
if (
|
|
6878
|
-
if ("device" in
|
|
6879
|
-
fds.installAt(
|
|
6892
|
+
for (const [n, slot2] of stdio.entries()) fds.installAt(n, this.openSlot(slot2, n, captured));
|
|
6893
|
+
for (const slot2 of inherit2) {
|
|
6894
|
+
if (slot2.fd <= 2) continue;
|
|
6895
|
+
if ("device" in slot2) {
|
|
6896
|
+
fds.installAt(slot2.fd, deviceFile(slot2.device, slot2.access));
|
|
6880
6897
|
continue;
|
|
6881
6898
|
}
|
|
6882
|
-
fds.installAt(
|
|
6883
|
-
if (
|
|
6899
|
+
fds.installAt(slot2.fd, this.parentFds.get(slot2.kernel).retain());
|
|
6900
|
+
if (slot2.flags !== void 0) fds.setStatusFlags(slot2.fd, slot2.flags);
|
|
6884
6901
|
}
|
|
6885
6902
|
} catch (e) {
|
|
6886
6903
|
await fds.closeAll();
|
|
@@ -6921,15 +6938,15 @@ var ChildTable = class {
|
|
|
6921
6938
|
this.watchers.set(pid, listener);
|
|
6922
6939
|
if (child.stoppedBy !== void 0) listener("stopped", child.stoppedBy);
|
|
6923
6940
|
}
|
|
6924
|
-
openSlot(
|
|
6925
|
-
if ("fd" in
|
|
6926
|
-
if ("input" in
|
|
6927
|
-
if ("device" in
|
|
6928
|
-
if ("dir" in
|
|
6929
|
-
if ("capture" in
|
|
6941
|
+
openSlot(slot2, n, captured) {
|
|
6942
|
+
if ("fd" in slot2) return this.parentFds.get(slot2.fd).retain();
|
|
6943
|
+
if ("input" in slot2) return bytesSource(slot2.input);
|
|
6944
|
+
if ("device" in slot2) return deviceFile(slot2.device, slot2.access);
|
|
6945
|
+
if ("dir" in slot2) return heldFile({ dir: slot2.dir });
|
|
6946
|
+
if ("capture" in slot2) {
|
|
6930
6947
|
const chunks = [];
|
|
6931
6948
|
captured.set(n, chunks);
|
|
6932
|
-
return sinkFile((
|
|
6949
|
+
return sinkFile(capturing(chunks, slot2.max, slot2.overflow));
|
|
6933
6950
|
}
|
|
6934
6951
|
return deviceFile("null");
|
|
6935
6952
|
}
|
|
@@ -6996,11 +7013,11 @@ var ChildTable = class {
|
|
|
6996
7013
|
pids() {
|
|
6997
7014
|
return [...this.children.keys()];
|
|
6998
7015
|
}
|
|
6999
|
-
captured(pid,
|
|
7016
|
+
captured(pid, slot2) {
|
|
7000
7017
|
const slots = this.leftovers.get(pid);
|
|
7001
|
-
const chunks = slots?.get(
|
|
7018
|
+
const chunks = slots?.get(slot2);
|
|
7002
7019
|
if (!slots || !chunks) return new Uint8Array(0);
|
|
7003
|
-
slots.delete(
|
|
7020
|
+
slots.delete(slot2);
|
|
7004
7021
|
if (slots.size === 0) this.leftovers.delete(pid);
|
|
7005
7022
|
return concat3(chunks);
|
|
7006
7023
|
}
|
|
@@ -8853,8 +8870,10 @@ var EARLY_WHOLE_FILE = 64 * 1024;
|
|
|
8853
8870
|
|
|
8854
8871
|
// src/process/process-fds.ts
|
|
8855
8872
|
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
8873
|
+
var pinnedRoot;
|
|
8874
|
+
var rootKind = () => globalThis.navigator?.storage ? "opfs" : "memory";
|
|
8856
8875
|
function mountTable(mounts = []) {
|
|
8857
|
-
const root =
|
|
8876
|
+
const root = pinnedRoot ?? rootKind();
|
|
8858
8877
|
const lines2 = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
8859
8878
|
for (const m of mounts) {
|
|
8860
8879
|
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
@@ -9232,6 +9251,7 @@ var HOST_OPS = [
|
|
|
9232
9251
|
"async-resolve",
|
|
9233
9252
|
"async-hold",
|
|
9234
9253
|
"async-cancel",
|
|
9254
|
+
"async-settle",
|
|
9235
9255
|
"async-close"
|
|
9236
9256
|
];
|
|
9237
9257
|
var json3 = (value) => ({ ok: true, kind: "json", json: value });
|
|
@@ -9263,12 +9283,16 @@ var LockTable = class {
|
|
|
9263
9283
|
for (const path of [...this.held.keys()]) this.unlock(pid, path);
|
|
9264
9284
|
}
|
|
9265
9285
|
};
|
|
9286
|
+
var KEPT_OPS = /* @__PURE__ */ new Set(["fd-write"]);
|
|
9287
|
+
var unknownSettled = false;
|
|
9266
9288
|
var AsyncOps = class {
|
|
9267
9289
|
next = 1;
|
|
9268
9290
|
results = /* @__PURE__ */ new Map();
|
|
9269
9291
|
ready = [];
|
|
9270
9292
|
running = /* @__PURE__ */ new Map();
|
|
9271
9293
|
waiters = /* @__PURE__ */ new Set();
|
|
9294
|
+
taken = /* @__PURE__ */ new Map();
|
|
9295
|
+
kept = /* @__PURE__ */ new Set();
|
|
9272
9296
|
closed = false;
|
|
9273
9297
|
run;
|
|
9274
9298
|
onReady;
|
|
@@ -9278,6 +9302,7 @@ var AsyncOps = class {
|
|
|
9278
9302
|
}
|
|
9279
9303
|
submit(req) {
|
|
9280
9304
|
const id2 = this.hold();
|
|
9305
|
+
if (KEPT_OPS.has(req.op)) this.kept.add(id2);
|
|
9281
9306
|
const running = new AbortController();
|
|
9282
9307
|
this.running.set(id2, running);
|
|
9283
9308
|
this.run(req, running.signal).then(
|
|
@@ -9301,9 +9326,26 @@ var AsyncOps = class {
|
|
|
9301
9326
|
const result = this.results.get(id2);
|
|
9302
9327
|
if (!result) throw new KernelError("EAGAIN");
|
|
9303
9328
|
this.forget(id2);
|
|
9329
|
+
if (this.kept.delete(id2)) this.taken.set(id2, result);
|
|
9304
9330
|
return result;
|
|
9305
9331
|
}
|
|
9332
|
+
ack(ids) {
|
|
9333
|
+
for (const id2 of ids) this.taken.delete(id2);
|
|
9334
|
+
}
|
|
9335
|
+
async settle(ids) {
|
|
9336
|
+
const never = new AbortController().signal;
|
|
9337
|
+
while (ids.some((id2) => this.running.has(id2))) await this.sleep(void 0, never);
|
|
9338
|
+
return ids.map((id2) => {
|
|
9339
|
+
const result = this.results.get(id2) ?? this.taken.get(id2) ?? null;
|
|
9340
|
+
if (!result && !unknownSettled) {
|
|
9341
|
+
unknownSettled = true;
|
|
9342
|
+
console.warn(`async-settle: no result for op ${id2}; its write counts as made`);
|
|
9343
|
+
}
|
|
9344
|
+
return result;
|
|
9345
|
+
});
|
|
9346
|
+
}
|
|
9306
9347
|
cancel(id2) {
|
|
9348
|
+
this.kept.delete(id2);
|
|
9307
9349
|
this.running.get(id2)?.abort();
|
|
9308
9350
|
this.forget(id2);
|
|
9309
9351
|
}
|
|
@@ -9379,6 +9421,7 @@ async function hostSyscall(req, ctx) {
|
|
|
9379
9421
|
return done2;
|
|
9380
9422
|
case "async-submit":
|
|
9381
9423
|
if (!ctx.valid(req.req)) throw new KernelError("EINVAL");
|
|
9424
|
+
if (req.ack) ctx.ops.ack(req.ack);
|
|
9382
9425
|
return json3(ctx.ops.submit(req.req));
|
|
9383
9426
|
case "async-wait":
|
|
9384
9427
|
return json3(await ctx.ops.wait(req.timeoutMs, ctx.blocking));
|
|
@@ -9391,6 +9434,8 @@ async function hostSyscall(req, ctx) {
|
|
|
9391
9434
|
case "async-cancel":
|
|
9392
9435
|
ctx.ops.cancel(req.id);
|
|
9393
9436
|
return done2;
|
|
9437
|
+
case "async-settle":
|
|
9438
|
+
return json3(await ctx.ops.settle(req.ids));
|
|
9394
9439
|
case "async-close":
|
|
9395
9440
|
ctx.ops.close();
|
|
9396
9441
|
return done2;
|
|
@@ -9898,8 +9943,8 @@ var KernelTty = class {
|
|
|
9898
9943
|
get canonical() {
|
|
9899
9944
|
return (this.termios.c_lflag & ICANON) !== 0;
|
|
9900
9945
|
}
|
|
9901
|
-
cc(
|
|
9902
|
-
return this.termios.c_cc[
|
|
9946
|
+
cc(slot2) {
|
|
9947
|
+
return this.termios.c_cc[slot2] ?? 0;
|
|
9903
9948
|
}
|
|
9904
9949
|
key(input) {
|
|
9905
9950
|
const { c_iflag, c_lflag } = this.termios;
|
|
@@ -10254,6 +10299,84 @@ function ptySyscall(req, ctx) {
|
|
|
10254
10299
|
}
|
|
10255
10300
|
}
|
|
10256
10301
|
|
|
10302
|
+
// src/kernel/run-child.ts
|
|
10303
|
+
var RUN_CAPTURE_CAP = 64 * 1024 * 1024;
|
|
10304
|
+
var RUN_MAX_BUFFER = 1024 * 1024;
|
|
10305
|
+
function capLimit(maxBuffer) {
|
|
10306
|
+
const asked = maxBuffer === void 0 ? RUN_MAX_BUFFER : maxBuffer;
|
|
10307
|
+
return Math.max(0, Math.min(asked, RUN_CAPTURE_CAP));
|
|
10308
|
+
}
|
|
10309
|
+
function slot(how, n, extra) {
|
|
10310
|
+
if (how === "inherit") return { fd: n };
|
|
10311
|
+
if (how === "ignore") return { none: true };
|
|
10312
|
+
return extra;
|
|
10313
|
+
}
|
|
10314
|
+
function frame2(outcome, out, err) {
|
|
10315
|
+
const head = new TextEncoder().encode(JSON.stringify(outcome));
|
|
10316
|
+
const bytes = new Uint8Array(4 + head.length + out.length + err.length);
|
|
10317
|
+
new DataView(bytes.buffer).setUint32(0, head.length, true);
|
|
10318
|
+
bytes.set(head, 4);
|
|
10319
|
+
bytes.set(out, 4 + head.length);
|
|
10320
|
+
bytes.set(err, 4 + head.length + out.length);
|
|
10321
|
+
return bytes;
|
|
10322
|
+
}
|
|
10323
|
+
async function reaped(deps, pid) {
|
|
10324
|
+
for (; ; ) {
|
|
10325
|
+
try {
|
|
10326
|
+
return (await deps.children.wait(pid, false, deps.interrupt()))[1];
|
|
10327
|
+
} catch (e) {
|
|
10328
|
+
if (!(e instanceof KernelError && e.code === "EINTR") || deps.dying()) throw e;
|
|
10329
|
+
}
|
|
10330
|
+
}
|
|
10331
|
+
}
|
|
10332
|
+
async function runChild(req, deps) {
|
|
10333
|
+
const max = capLimit(req.maxBuffer);
|
|
10334
|
+
let failure2;
|
|
10335
|
+
let pid = 0;
|
|
10336
|
+
const kill = () => void Promise.allSettled([deps.kill(pid, req.killSignal)]);
|
|
10337
|
+
const stop = (code) => {
|
|
10338
|
+
if (failure2 !== void 0) return;
|
|
10339
|
+
failure2 = code;
|
|
10340
|
+
if (pid !== 0) kill();
|
|
10341
|
+
};
|
|
10342
|
+
const capture = () => ({ capture: true, max, overflow: () => stop("ENOBUFS") });
|
|
10343
|
+
const stdio = [
|
|
10344
|
+
slot(req.stdin, 0, { input: req.input ?? new Uint8Array(0) }),
|
|
10345
|
+
slot(req.stdout, 1, capture()),
|
|
10346
|
+
slot(req.stderr, 2, capture())
|
|
10347
|
+
];
|
|
10348
|
+
try {
|
|
10349
|
+
pid = await deps.children.spawn(
|
|
10350
|
+
{ file: req.file, argv: req.argv, env: req.env, cwd: req.cwd },
|
|
10351
|
+
stdio
|
|
10352
|
+
);
|
|
10353
|
+
} catch (e) {
|
|
10354
|
+
if (!(e instanceof SpawnError)) throw e;
|
|
10355
|
+
const outcome2 = { pid: 0, status: null, error: { code: e.code }, out: 0, err: 0 };
|
|
10356
|
+
return frame2(outcome2, new Uint8Array(0), new Uint8Array(0));
|
|
10357
|
+
}
|
|
10358
|
+
if (failure2 !== void 0) kill();
|
|
10359
|
+
const timer = req.timeoutMs !== void 0 && req.timeoutMs > 0 ? setTimeout(() => stop("ETIMEDOUT"), req.timeoutMs) : void 0;
|
|
10360
|
+
let status;
|
|
10361
|
+
try {
|
|
10362
|
+
status = await reaped(deps, pid);
|
|
10363
|
+
} finally {
|
|
10364
|
+
clearTimeout(timer);
|
|
10365
|
+
}
|
|
10366
|
+
const out = deps.children.captured(pid, 1);
|
|
10367
|
+
const err = deps.children.captured(pid, 2);
|
|
10368
|
+
const termsig = status & 127;
|
|
10369
|
+
const outcome = {
|
|
10370
|
+
pid,
|
|
10371
|
+
status: termsig ? null : status >> 8 & 255,
|
|
10372
|
+
...termsig ? { signal: termsig } : {},
|
|
10373
|
+
...failure2 !== void 0 ? { error: { code: failure2 } } : {},
|
|
10374
|
+
out: out.length,
|
|
10375
|
+
err: err.length
|
|
10376
|
+
};
|
|
10377
|
+
return frame2(outcome, out, err);
|
|
10378
|
+
}
|
|
10379
|
+
|
|
10257
10380
|
// src/kernel/select.ts
|
|
10258
10381
|
function ready(fds, read, write) {
|
|
10259
10382
|
const hangup = /* @__PURE__ */ new Set();
|
|
@@ -11050,6 +11173,8 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
11050
11173
|
"proc-spawn",
|
|
11051
11174
|
"proc-wait",
|
|
11052
11175
|
"proc-captured",
|
|
11176
|
+
"proc-run",
|
|
11177
|
+
"proc-exit",
|
|
11053
11178
|
"proc-fork",
|
|
11054
11179
|
"proc-kill",
|
|
11055
11180
|
"thread-kill",
|
|
@@ -11170,6 +11295,14 @@ var WasmProcess = class {
|
|
|
11170
11295
|
else this.adoptExec(pid);
|
|
11171
11296
|
return pid;
|
|
11172
11297
|
}
|
|
11298
|
+
run(req) {
|
|
11299
|
+
return runChild(req, {
|
|
11300
|
+
children: this.children,
|
|
11301
|
+
kill: (pid, sig) => this.options.kill?.(pid, sig),
|
|
11302
|
+
interrupt: () => this.interrupt.signal,
|
|
11303
|
+
dying: () => this.dying
|
|
11304
|
+
});
|
|
11305
|
+
}
|
|
11173
11306
|
adoptExec(pid) {
|
|
11174
11307
|
this.execChild = pid;
|
|
11175
11308
|
this.children.watch(pid, (state, sig) => state === "stopped" ? this.stop(sig) : this.cont());
|
|
@@ -11718,6 +11851,12 @@ var WasmProcess = class {
|
|
|
11718
11851
|
return { ok: true, kind: "json", json: await this.spawn(req) };
|
|
11719
11852
|
case "proc-wait":
|
|
11720
11853
|
return { ok: true, kind: "json", json: await this.procWait(req, cancelled) };
|
|
11854
|
+
case "proc-run":
|
|
11855
|
+
return { ok: true, kind: "bytes", bytes: await this.run(req) };
|
|
11856
|
+
case "proc-exit":
|
|
11857
|
+
if (!this.options.exitNow) throw new KernelError("ENOSYS");
|
|
11858
|
+
this.options.exitNow(req.status & 255);
|
|
11859
|
+
return DYING;
|
|
11721
11860
|
case "proc-identity":
|
|
11722
11861
|
return { ok: true, kind: "json", json: await this.options.identity?.() ?? null };
|
|
11723
11862
|
case "proc-exec": {
|
|
@@ -12124,6 +12263,7 @@ function processOptions(opts, header3, hooks, created3) {
|
|
|
12124
12263
|
hasPending: () => Atomics.load(header3, SAB_I_SIGNALS) !== 0 || Atomics.load(header3, SAB_I_TIMERS) !== 0,
|
|
12125
12264
|
raise: hooks.raise,
|
|
12126
12265
|
threadKill: hooks.threadKill,
|
|
12266
|
+
...hooks.exitNow ? { exitNow: hooks.exitNow } : {},
|
|
12127
12267
|
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header3, SAB_I_SIGNALS) } : {}
|
|
12128
12268
|
};
|
|
12129
12269
|
}
|
|
@@ -12140,7 +12280,8 @@ function spawnWasmProcess(opts) {
|
|
|
12140
12280
|
header3,
|
|
12141
12281
|
{
|
|
12142
12282
|
raise: (sig) => signal(sig),
|
|
12143
|
-
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process.signalMasks().caught, sig)
|
|
12283
|
+
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process.signalMasks().caught, sig),
|
|
12284
|
+
...opts.program.abi === "js" ? { exitNow: (code) => exitNow(code) } : {}
|
|
12144
12285
|
},
|
|
12145
12286
|
created3
|
|
12146
12287
|
)
|
|
@@ -12181,12 +12322,15 @@ function spawnWasmProcess(opts) {
|
|
|
12181
12322
|
() => settle3(code)
|
|
12182
12323
|
);
|
|
12183
12324
|
};
|
|
12325
|
+
const exitNow = (code) => {
|
|
12326
|
+
queueMicrotask(() => finish(...dying.status(code)));
|
|
12327
|
+
};
|
|
12184
12328
|
const handle = (data) => {
|
|
12185
12329
|
if (data?.type === WASM_PROCESS_EXIT) {
|
|
12186
12330
|
finish(...dying.status(data.code));
|
|
12187
12331
|
} else if (data?.type === WASM_PROCESS_ERROR) {
|
|
12188
12332
|
if (!dying.ending) opts.onError?.(String(data.message));
|
|
12189
|
-
finish(...dying.status(
|
|
12333
|
+
finish(...dying.status(data.code));
|
|
12190
12334
|
} else if (data?.type === WASM_THREAD_SPAWN && data.thread) {
|
|
12191
12335
|
spawnThread(data.thread);
|
|
12192
12336
|
}
|
|
@@ -12916,15 +13060,15 @@ function granted(handle) {
|
|
|
12916
13060
|
);
|
|
12917
13061
|
}
|
|
12918
13062
|
function removableMedium(onLost, open = (handle) => new OpfsFs(handle)) {
|
|
12919
|
-
const
|
|
13063
|
+
const slot2 = mediumSlot(
|
|
12920
13064
|
async (err, handle) => denied(err) && !await granted(handle),
|
|
12921
13065
|
onLost
|
|
12922
13066
|
);
|
|
12923
13067
|
return {
|
|
12924
|
-
handlers:
|
|
12925
|
-
present:
|
|
12926
|
-
insert: (handle) =>
|
|
12927
|
-
eject:
|
|
13068
|
+
handlers: slot2.handlers,
|
|
13069
|
+
present: slot2.present,
|
|
13070
|
+
insert: (handle) => slot2.insert(handle, kernelFsHandlers(open(handle))),
|
|
13071
|
+
eject: slot2.eject
|
|
12928
13072
|
};
|
|
12929
13073
|
}
|
|
12930
13074
|
|
|
@@ -13708,7 +13852,7 @@ function grantConnect(hook, fetch2, liveness = {}) {
|
|
|
13708
13852
|
async function openHostfs(spec, connect, timing = {}) {
|
|
13709
13853
|
const readonly2 = spec.options?.ro !== void 0;
|
|
13710
13854
|
const { port1, port2 } = new MessageChannel();
|
|
13711
|
-
const
|
|
13855
|
+
const slot2 = mediumSlot(
|
|
13712
13856
|
async (err) => unreachable(err),
|
|
13713
13857
|
() => watching.kick()
|
|
13714
13858
|
);
|
|
@@ -13721,7 +13865,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13721
13865
|
});
|
|
13722
13866
|
const served = serveFilesystem(
|
|
13723
13867
|
port2,
|
|
13724
|
-
{ ...
|
|
13868
|
+
{ ...slot2.handlers, mount: ranged2 },
|
|
13725
13869
|
{
|
|
13726
13870
|
symlinks: true,
|
|
13727
13871
|
chmod: true,
|
|
@@ -13735,12 +13879,12 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13735
13879
|
connect: () => connect(spec.source, { readonly: readonly2 }),
|
|
13736
13880
|
up(client) {
|
|
13737
13881
|
active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);
|
|
13738
|
-
|
|
13882
|
+
slot2.insert(client, handlers);
|
|
13739
13883
|
served.invalidate(true);
|
|
13740
13884
|
},
|
|
13741
13885
|
event: (event) => served.invalidate(invalidation(event)),
|
|
13742
13886
|
down() {
|
|
13743
|
-
|
|
13887
|
+
slot2.eject();
|
|
13744
13888
|
served.invalidate(true);
|
|
13745
13889
|
},
|
|
13746
13890
|
...timing
|
|
@@ -13750,7 +13894,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13750
13894
|
await watching.ready;
|
|
13751
13895
|
return {
|
|
13752
13896
|
port: port1,
|
|
13753
|
-
present:
|
|
13897
|
+
present: slot2.present,
|
|
13754
13898
|
dispose() {
|
|
13755
13899
|
stop.abort();
|
|
13756
13900
|
port1.close();
|
|
@@ -15044,16 +15188,16 @@ var Launcher = class {
|
|
|
15044
15188
|
}
|
|
15045
15189
|
async insert(target, handle, source) {
|
|
15046
15190
|
const at = normalizePath(target);
|
|
15047
|
-
const
|
|
15048
|
-
if (!
|
|
15049
|
-
if (source !== void 0 && source !== `fsa:${
|
|
15191
|
+
const slot2 = this.removable.get(at);
|
|
15192
|
+
if (!slot2) throw fsError("EINVAL", `${at} is not a removable mount`);
|
|
15193
|
+
if (source !== void 0 && source !== `fsa:${slot2.id}`) {
|
|
15050
15194
|
throw fsError("EINVAL", `${at} is no longer the drive ${source}`);
|
|
15051
15195
|
}
|
|
15052
15196
|
if (!await granted(handle)) throw fsError("EACCES", `${at}: no permission for this folder`);
|
|
15053
|
-
this.inserted.set(
|
|
15054
|
-
await this.media.put(
|
|
15055
|
-
|
|
15056
|
-
|
|
15197
|
+
this.inserted.set(slot2.id, handle);
|
|
15198
|
+
await this.media.put(slot2.id, handle);
|
|
15199
|
+
slot2.medium.insert(handle);
|
|
15200
|
+
slot2.served.invalidate(true);
|
|
15057
15201
|
void this.unlinked.sweep(at);
|
|
15058
15202
|
}
|
|
15059
15203
|
umount(target, detach = false) {
|