@ai-ecoverse/slicc-kernel 1.64.2 → 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 +7 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +179 -37
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +362 -187
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +179 -37
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +362 -187
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -5264,6 +5264,23 @@ var CONTINUED_STATUS = 65535;
|
|
|
5264
5264
|
function waitStatus(code, termsig) {
|
|
5265
5265
|
return termsig ? termsig & 127 : (code & 255) << 8;
|
|
5266
5266
|
}
|
|
5267
|
+
function capturing(chunks2, max = Number.POSITIVE_INFINITY, overflow) {
|
|
5268
|
+
let size = 0;
|
|
5269
|
+
let over = false;
|
|
5270
|
+
return (bytes) => {
|
|
5271
|
+
if (over) return;
|
|
5272
|
+
const room = max - size;
|
|
5273
|
+
if (bytes.length > room) {
|
|
5274
|
+
over = true;
|
|
5275
|
+
if (room > 0) chunks2.push(bytes.slice(0, room));
|
|
5276
|
+
size = max;
|
|
5277
|
+
overflow?.();
|
|
5278
|
+
return;
|
|
5279
|
+
}
|
|
5280
|
+
chunks2.push(bytes);
|
|
5281
|
+
size += bytes.length;
|
|
5282
|
+
};
|
|
5283
|
+
}
|
|
5267
5284
|
function concat2(chunks2) {
|
|
5268
5285
|
const out = new Uint8Array(chunks2.reduce((n, c) => n + c.length, 0));
|
|
5269
5286
|
let offset = 0;
|
|
@@ -5297,15 +5314,15 @@ var ChildTable = class {
|
|
|
5297
5314
|
const fds = new FdTable();
|
|
5298
5315
|
const captured = /* @__PURE__ */ new Map();
|
|
5299
5316
|
try {
|
|
5300
|
-
for (const [n,
|
|
5301
|
-
for (const
|
|
5302
|
-
if (
|
|
5303
|
-
if ("device" in
|
|
5304
|
-
fds.installAt(
|
|
5317
|
+
for (const [n, slot2] of stdio.entries()) fds.installAt(n, this.openSlot(slot2, n, captured));
|
|
5318
|
+
for (const slot2 of inherit2) {
|
|
5319
|
+
if (slot2.fd <= 2) continue;
|
|
5320
|
+
if ("device" in slot2) {
|
|
5321
|
+
fds.installAt(slot2.fd, deviceFile(slot2.device, slot2.access));
|
|
5305
5322
|
continue;
|
|
5306
5323
|
}
|
|
5307
|
-
fds.installAt(
|
|
5308
|
-
if (
|
|
5324
|
+
fds.installAt(slot2.fd, this.parentFds.get(slot2.kernel).retain());
|
|
5325
|
+
if (slot2.flags !== void 0) fds.setStatusFlags(slot2.fd, slot2.flags);
|
|
5309
5326
|
}
|
|
5310
5327
|
} catch (e) {
|
|
5311
5328
|
await fds.closeAll();
|
|
@@ -5346,15 +5363,15 @@ var ChildTable = class {
|
|
|
5346
5363
|
this.watchers.set(pid, listener);
|
|
5347
5364
|
if (child.stoppedBy !== void 0) listener("stopped", child.stoppedBy);
|
|
5348
5365
|
}
|
|
5349
|
-
openSlot(
|
|
5350
|
-
if ("fd" in
|
|
5351
|
-
if ("input" in
|
|
5352
|
-
if ("device" in
|
|
5353
|
-
if ("dir" in
|
|
5354
|
-
if ("capture" in
|
|
5366
|
+
openSlot(slot2, n, captured) {
|
|
5367
|
+
if ("fd" in slot2) return this.parentFds.get(slot2.fd).retain();
|
|
5368
|
+
if ("input" in slot2) return bytesSource(slot2.input);
|
|
5369
|
+
if ("device" in slot2) return deviceFile(slot2.device, slot2.access);
|
|
5370
|
+
if ("dir" in slot2) return heldFile({ dir: slot2.dir });
|
|
5371
|
+
if ("capture" in slot2) {
|
|
5355
5372
|
const chunks2 = [];
|
|
5356
5373
|
captured.set(n, chunks2);
|
|
5357
|
-
return sinkFile((
|
|
5374
|
+
return sinkFile(capturing(chunks2, slot2.max, slot2.overflow));
|
|
5358
5375
|
}
|
|
5359
5376
|
return deviceFile("null");
|
|
5360
5377
|
}
|
|
@@ -5421,11 +5438,11 @@ var ChildTable = class {
|
|
|
5421
5438
|
pids() {
|
|
5422
5439
|
return [...this.children.keys()];
|
|
5423
5440
|
}
|
|
5424
|
-
captured(pid,
|
|
5441
|
+
captured(pid, slot2) {
|
|
5425
5442
|
const slots = this.leftovers.get(pid);
|
|
5426
|
-
const chunks2 = slots?.get(
|
|
5443
|
+
const chunks2 = slots?.get(slot2);
|
|
5427
5444
|
if (!slots || !chunks2) return new Uint8Array(0);
|
|
5428
|
-
slots.delete(
|
|
5445
|
+
slots.delete(slot2);
|
|
5429
5446
|
if (slots.size === 0) this.leftovers.delete(pid);
|
|
5430
5447
|
return concat2(chunks2);
|
|
5431
5448
|
}
|
|
@@ -7686,6 +7703,7 @@ var HOST_OPS = [
|
|
|
7686
7703
|
"async-resolve",
|
|
7687
7704
|
"async-hold",
|
|
7688
7705
|
"async-cancel",
|
|
7706
|
+
"async-settle",
|
|
7689
7707
|
"async-close"
|
|
7690
7708
|
];
|
|
7691
7709
|
var json3 = (value) => ({ ok: true, kind: "json", json: value });
|
|
@@ -7717,12 +7735,16 @@ var LockTable = class {
|
|
|
7717
7735
|
for (const path of [...this.held.keys()]) this.unlock(pid, path);
|
|
7718
7736
|
}
|
|
7719
7737
|
};
|
|
7738
|
+
var KEPT_OPS = /* @__PURE__ */ new Set(["fd-write"]);
|
|
7739
|
+
var unknownSettled = false;
|
|
7720
7740
|
var AsyncOps = class {
|
|
7721
7741
|
next = 1;
|
|
7722
7742
|
results = /* @__PURE__ */ new Map();
|
|
7723
7743
|
ready = [];
|
|
7724
7744
|
running = /* @__PURE__ */ new Map();
|
|
7725
7745
|
waiters = /* @__PURE__ */ new Set();
|
|
7746
|
+
taken = /* @__PURE__ */ new Map();
|
|
7747
|
+
kept = /* @__PURE__ */ new Set();
|
|
7726
7748
|
closed = false;
|
|
7727
7749
|
run;
|
|
7728
7750
|
onReady;
|
|
@@ -7732,6 +7754,7 @@ var AsyncOps = class {
|
|
|
7732
7754
|
}
|
|
7733
7755
|
submit(req) {
|
|
7734
7756
|
const id2 = this.hold();
|
|
7757
|
+
if (KEPT_OPS.has(req.op)) this.kept.add(id2);
|
|
7735
7758
|
const running = new AbortController();
|
|
7736
7759
|
this.running.set(id2, running);
|
|
7737
7760
|
this.run(req, running.signal).then(
|
|
@@ -7755,9 +7778,26 @@ var AsyncOps = class {
|
|
|
7755
7778
|
const result = this.results.get(id2);
|
|
7756
7779
|
if (!result) throw new KernelError("EAGAIN");
|
|
7757
7780
|
this.forget(id2);
|
|
7781
|
+
if (this.kept.delete(id2)) this.taken.set(id2, result);
|
|
7758
7782
|
return result;
|
|
7759
7783
|
}
|
|
7784
|
+
ack(ids) {
|
|
7785
|
+
for (const id2 of ids) this.taken.delete(id2);
|
|
7786
|
+
}
|
|
7787
|
+
async settle(ids) {
|
|
7788
|
+
const never = new AbortController().signal;
|
|
7789
|
+
while (ids.some((id2) => this.running.has(id2))) await this.sleep(void 0, never);
|
|
7790
|
+
return ids.map((id2) => {
|
|
7791
|
+
const result = this.results.get(id2) ?? this.taken.get(id2) ?? null;
|
|
7792
|
+
if (!result && !unknownSettled) {
|
|
7793
|
+
unknownSettled = true;
|
|
7794
|
+
console.warn(`async-settle: no result for op ${id2}; its write counts as made`);
|
|
7795
|
+
}
|
|
7796
|
+
return result;
|
|
7797
|
+
});
|
|
7798
|
+
}
|
|
7760
7799
|
cancel(id2) {
|
|
7800
|
+
this.kept.delete(id2);
|
|
7761
7801
|
this.running.get(id2)?.abort();
|
|
7762
7802
|
this.forget(id2);
|
|
7763
7803
|
}
|
|
@@ -7833,6 +7873,7 @@ async function hostSyscall(req, ctx) {
|
|
|
7833
7873
|
return done2;
|
|
7834
7874
|
case "async-submit":
|
|
7835
7875
|
if (!ctx.valid(req.req)) throw new KernelError("EINVAL");
|
|
7876
|
+
if (req.ack) ctx.ops.ack(req.ack);
|
|
7836
7877
|
return json3(ctx.ops.submit(req.req));
|
|
7837
7878
|
case "async-wait":
|
|
7838
7879
|
return json3(await ctx.ops.wait(req.timeoutMs, ctx.blocking));
|
|
@@ -7845,6 +7886,8 @@ async function hostSyscall(req, ctx) {
|
|
|
7845
7886
|
case "async-cancel":
|
|
7846
7887
|
ctx.ops.cancel(req.id);
|
|
7847
7888
|
return done2;
|
|
7889
|
+
case "async-settle":
|
|
7890
|
+
return json3(await ctx.ops.settle(req.ids));
|
|
7848
7891
|
case "async-close":
|
|
7849
7892
|
ctx.ops.close();
|
|
7850
7893
|
return done2;
|
|
@@ -9673,8 +9716,8 @@ var KernelTty = class {
|
|
|
9673
9716
|
get canonical() {
|
|
9674
9717
|
return (this.termios.c_lflag & ICANON) !== 0;
|
|
9675
9718
|
}
|
|
9676
|
-
cc(
|
|
9677
|
-
return this.termios.c_cc[
|
|
9719
|
+
cc(slot2) {
|
|
9720
|
+
return this.termios.c_cc[slot2] ?? 0;
|
|
9678
9721
|
}
|
|
9679
9722
|
key(input) {
|
|
9680
9723
|
const { c_iflag, c_lflag } = this.termios;
|
|
@@ -10029,6 +10072,84 @@ function ptySyscall(req, ctx) {
|
|
|
10029
10072
|
}
|
|
10030
10073
|
}
|
|
10031
10074
|
|
|
10075
|
+
// src/kernel/run-child.ts
|
|
10076
|
+
var RUN_CAPTURE_CAP = 64 * 1024 * 1024;
|
|
10077
|
+
var RUN_MAX_BUFFER = 1024 * 1024;
|
|
10078
|
+
function capLimit(maxBuffer) {
|
|
10079
|
+
const asked = maxBuffer === void 0 ? RUN_MAX_BUFFER : maxBuffer;
|
|
10080
|
+
return Math.max(0, Math.min(asked, RUN_CAPTURE_CAP));
|
|
10081
|
+
}
|
|
10082
|
+
function slot(how, n, extra) {
|
|
10083
|
+
if (how === "inherit") return { fd: n };
|
|
10084
|
+
if (how === "ignore") return { none: true };
|
|
10085
|
+
return extra;
|
|
10086
|
+
}
|
|
10087
|
+
function frame2(outcome, out, err) {
|
|
10088
|
+
const head = new TextEncoder().encode(JSON.stringify(outcome));
|
|
10089
|
+
const bytes = new Uint8Array(4 + head.length + out.length + err.length);
|
|
10090
|
+
new DataView(bytes.buffer).setUint32(0, head.length, true);
|
|
10091
|
+
bytes.set(head, 4);
|
|
10092
|
+
bytes.set(out, 4 + head.length);
|
|
10093
|
+
bytes.set(err, 4 + head.length + out.length);
|
|
10094
|
+
return bytes;
|
|
10095
|
+
}
|
|
10096
|
+
async function reaped(deps, pid) {
|
|
10097
|
+
for (; ; ) {
|
|
10098
|
+
try {
|
|
10099
|
+
return (await deps.children.wait(pid, false, deps.interrupt()))[1];
|
|
10100
|
+
} catch (e) {
|
|
10101
|
+
if (!(e instanceof KernelError && e.code === "EINTR") || deps.dying()) throw e;
|
|
10102
|
+
}
|
|
10103
|
+
}
|
|
10104
|
+
}
|
|
10105
|
+
async function runChild(req, deps) {
|
|
10106
|
+
const max = capLimit(req.maxBuffer);
|
|
10107
|
+
let failure;
|
|
10108
|
+
let pid = 0;
|
|
10109
|
+
const kill = () => void Promise.allSettled([deps.kill(pid, req.killSignal)]);
|
|
10110
|
+
const stop = (code) => {
|
|
10111
|
+
if (failure !== void 0) return;
|
|
10112
|
+
failure = code;
|
|
10113
|
+
if (pid !== 0) kill();
|
|
10114
|
+
};
|
|
10115
|
+
const capture = () => ({ capture: true, max, overflow: () => stop("ENOBUFS") });
|
|
10116
|
+
const stdio = [
|
|
10117
|
+
slot(req.stdin, 0, { input: req.input ?? new Uint8Array(0) }),
|
|
10118
|
+
slot(req.stdout, 1, capture()),
|
|
10119
|
+
slot(req.stderr, 2, capture())
|
|
10120
|
+
];
|
|
10121
|
+
try {
|
|
10122
|
+
pid = await deps.children.spawn(
|
|
10123
|
+
{ file: req.file, argv: req.argv, env: req.env, cwd: req.cwd },
|
|
10124
|
+
stdio
|
|
10125
|
+
);
|
|
10126
|
+
} catch (e) {
|
|
10127
|
+
if (!(e instanceof SpawnError)) throw e;
|
|
10128
|
+
const outcome2 = { pid: 0, status: null, error: { code: e.code }, out: 0, err: 0 };
|
|
10129
|
+
return frame2(outcome2, new Uint8Array(0), new Uint8Array(0));
|
|
10130
|
+
}
|
|
10131
|
+
if (failure !== void 0) kill();
|
|
10132
|
+
const timer = req.timeoutMs !== void 0 && req.timeoutMs > 0 ? setTimeout(() => stop("ETIMEDOUT"), req.timeoutMs) : void 0;
|
|
10133
|
+
let status;
|
|
10134
|
+
try {
|
|
10135
|
+
status = await reaped(deps, pid);
|
|
10136
|
+
} finally {
|
|
10137
|
+
clearTimeout(timer);
|
|
10138
|
+
}
|
|
10139
|
+
const out = deps.children.captured(pid, 1);
|
|
10140
|
+
const err = deps.children.captured(pid, 2);
|
|
10141
|
+
const termsig = status & 127;
|
|
10142
|
+
const outcome = {
|
|
10143
|
+
pid,
|
|
10144
|
+
status: termsig ? null : status >> 8 & 255,
|
|
10145
|
+
...termsig ? { signal: termsig } : {},
|
|
10146
|
+
...failure !== void 0 ? { error: { code: failure } } : {},
|
|
10147
|
+
out: out.length,
|
|
10148
|
+
err: err.length
|
|
10149
|
+
};
|
|
10150
|
+
return frame2(outcome, out, err);
|
|
10151
|
+
}
|
|
10152
|
+
|
|
10032
10153
|
// src/kernel/select.ts
|
|
10033
10154
|
function ready(fds, read, write) {
|
|
10034
10155
|
const hangup = /* @__PURE__ */ new Set();
|
|
@@ -10825,6 +10946,8 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
10825
10946
|
"proc-spawn",
|
|
10826
10947
|
"proc-wait",
|
|
10827
10948
|
"proc-captured",
|
|
10949
|
+
"proc-run",
|
|
10950
|
+
"proc-exit",
|
|
10828
10951
|
"proc-fork",
|
|
10829
10952
|
"proc-kill",
|
|
10830
10953
|
"thread-kill",
|
|
@@ -10945,6 +11068,14 @@ var WasmProcess = class {
|
|
|
10945
11068
|
else this.adoptExec(pid);
|
|
10946
11069
|
return pid;
|
|
10947
11070
|
}
|
|
11071
|
+
run(req) {
|
|
11072
|
+
return runChild(req, {
|
|
11073
|
+
children: this.children,
|
|
11074
|
+
kill: (pid, sig) => this.options.kill?.(pid, sig),
|
|
11075
|
+
interrupt: () => this.interrupt.signal,
|
|
11076
|
+
dying: () => this.dying
|
|
11077
|
+
});
|
|
11078
|
+
}
|
|
10948
11079
|
adoptExec(pid) {
|
|
10949
11080
|
this.execChild = pid;
|
|
10950
11081
|
this.children.watch(pid, (state, sig) => state === "stopped" ? this.stop(sig) : this.cont());
|
|
@@ -11493,6 +11624,12 @@ var WasmProcess = class {
|
|
|
11493
11624
|
return { ok: true, kind: "json", json: await this.spawn(req) };
|
|
11494
11625
|
case "proc-wait":
|
|
11495
11626
|
return { ok: true, kind: "json", json: await this.procWait(req, cancelled) };
|
|
11627
|
+
case "proc-run":
|
|
11628
|
+
return { ok: true, kind: "bytes", bytes: await this.run(req) };
|
|
11629
|
+
case "proc-exit":
|
|
11630
|
+
if (!this.options.exitNow) throw new KernelError("ENOSYS");
|
|
11631
|
+
this.options.exitNow(req.status & 255);
|
|
11632
|
+
return DYING;
|
|
11496
11633
|
case "proc-identity":
|
|
11497
11634
|
return { ok: true, kind: "json", json: await this.options.identity?.() ?? null };
|
|
11498
11635
|
case "proc-exec": {
|
|
@@ -11899,6 +12036,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
11899
12036
|
hasPending: () => Atomics.load(header4, SAB_I_SIGNALS) !== 0 || Atomics.load(header4, SAB_I_TIMERS) !== 0,
|
|
11900
12037
|
raise: hooks.raise,
|
|
11901
12038
|
threadKill: hooks.threadKill,
|
|
12039
|
+
...hooks.exitNow ? { exitNow: hooks.exitNow } : {},
|
|
11902
12040
|
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header4, SAB_I_SIGNALS) } : {}
|
|
11903
12041
|
};
|
|
11904
12042
|
}
|
|
@@ -11915,7 +12053,8 @@ function spawnWasmProcess(opts) {
|
|
|
11915
12053
|
header4,
|
|
11916
12054
|
{
|
|
11917
12055
|
raise: (sig) => signal(sig),
|
|
11918
|
-
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig)
|
|
12056
|
+
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig),
|
|
12057
|
+
...opts.program.abi === "js" ? { exitNow: (code) => exitNow(code) } : {}
|
|
11919
12058
|
},
|
|
11920
12059
|
created3
|
|
11921
12060
|
)
|
|
@@ -11956,6 +12095,9 @@ function spawnWasmProcess(opts) {
|
|
|
11956
12095
|
() => settle(code)
|
|
11957
12096
|
);
|
|
11958
12097
|
};
|
|
12098
|
+
const exitNow = (code) => {
|
|
12099
|
+
queueMicrotask(() => finish(...dying.status(code)));
|
|
12100
|
+
};
|
|
11959
12101
|
const handle = (data) => {
|
|
11960
12102
|
if (data?.type === WASM_PROCESS_EXIT) {
|
|
11961
12103
|
finish(...dying.status(data.code));
|
|
@@ -12691,15 +12833,15 @@ function granted(handle) {
|
|
|
12691
12833
|
);
|
|
12692
12834
|
}
|
|
12693
12835
|
function removableMedium(onLost, open = (handle) => new OpfsFs(handle)) {
|
|
12694
|
-
const
|
|
12836
|
+
const slot2 = mediumSlot(
|
|
12695
12837
|
async (err, handle) => denied(err) && !await granted(handle),
|
|
12696
12838
|
onLost
|
|
12697
12839
|
);
|
|
12698
12840
|
return {
|
|
12699
|
-
handlers:
|
|
12700
|
-
present:
|
|
12701
|
-
insert: (handle) =>
|
|
12702
|
-
eject:
|
|
12841
|
+
handlers: slot2.handlers,
|
|
12842
|
+
present: slot2.present,
|
|
12843
|
+
insert: (handle) => slot2.insert(handle, kernelFsHandlers(open(handle))),
|
|
12844
|
+
eject: slot2.eject
|
|
12703
12845
|
};
|
|
12704
12846
|
}
|
|
12705
12847
|
|
|
@@ -13577,7 +13719,7 @@ function grantConnect(hook, fetch2, liveness = {}) {
|
|
|
13577
13719
|
async function openHostfs(spec, connect, timing = {}) {
|
|
13578
13720
|
const readonly2 = spec.options?.ro !== void 0;
|
|
13579
13721
|
const { port1, port2 } = new MessageChannel();
|
|
13580
|
-
const
|
|
13722
|
+
const slot2 = mediumSlot(
|
|
13581
13723
|
async (err) => unreachable(err),
|
|
13582
13724
|
() => watching.kick()
|
|
13583
13725
|
);
|
|
@@ -13590,7 +13732,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13590
13732
|
});
|
|
13591
13733
|
const served = serveFilesystem(
|
|
13592
13734
|
port2,
|
|
13593
|
-
{ ...
|
|
13735
|
+
{ ...slot2.handlers, mount: ranged2 },
|
|
13594
13736
|
{
|
|
13595
13737
|
symlinks: true,
|
|
13596
13738
|
chmod: true,
|
|
@@ -13604,12 +13746,12 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13604
13746
|
connect: () => connect(spec.source, { readonly: readonly2 }),
|
|
13605
13747
|
up(client) {
|
|
13606
13748
|
active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);
|
|
13607
|
-
|
|
13749
|
+
slot2.insert(client, handlers);
|
|
13608
13750
|
served.invalidate(true);
|
|
13609
13751
|
},
|
|
13610
13752
|
event: (event) => served.invalidate(invalidation(event)),
|
|
13611
13753
|
down() {
|
|
13612
|
-
|
|
13754
|
+
slot2.eject();
|
|
13613
13755
|
served.invalidate(true);
|
|
13614
13756
|
},
|
|
13615
13757
|
...timing
|
|
@@ -13619,7 +13761,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13619
13761
|
await watching.ready;
|
|
13620
13762
|
return {
|
|
13621
13763
|
port: port1,
|
|
13622
|
-
present:
|
|
13764
|
+
present: slot2.present,
|
|
13623
13765
|
dispose() {
|
|
13624
13766
|
stop.abort();
|
|
13625
13767
|
port1.close();
|
|
@@ -14922,16 +15064,16 @@ var Launcher = class {
|
|
|
14922
15064
|
}
|
|
14923
15065
|
async insert(target, handle, source) {
|
|
14924
15066
|
const at = normalizePath(target);
|
|
14925
|
-
const
|
|
14926
|
-
if (!
|
|
14927
|
-
if (source !== void 0 && source !== `fsa:${
|
|
15067
|
+
const slot2 = this.removable.get(at);
|
|
15068
|
+
if (!slot2) throw fsError("EINVAL", `${at} is not a removable mount`);
|
|
15069
|
+
if (source !== void 0 && source !== `fsa:${slot2.id}`) {
|
|
14928
15070
|
throw fsError("EINVAL", `${at} is no longer the drive ${source}`);
|
|
14929
15071
|
}
|
|
14930
15072
|
if (!await granted(handle)) throw fsError("EACCES", `${at}: no permission for this folder`);
|
|
14931
|
-
this.inserted.set(
|
|
14932
|
-
await this.media.put(
|
|
14933
|
-
|
|
14934
|
-
|
|
15073
|
+
this.inserted.set(slot2.id, handle);
|
|
15074
|
+
await this.media.put(slot2.id, handle);
|
|
15075
|
+
slot2.medium.insert(handle);
|
|
15076
|
+
slot2.served.invalidate(true);
|
|
14935
15077
|
void this.unlinked.sweep(at);
|
|
14936
15078
|
}
|
|
14937
15079
|
umount(target, detach = false) {
|