@ai-ecoverse/slicc-kernel 1.40.1 → 1.41.2
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 +1 -1
- package/dist/kernel-worker.js +233 -130
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +197 -64
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +255 -152
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +197 -64
- package/dist/process-worker.js.map +4 -4
- package/package.json +3 -3
package/dist/kernel-worker.js
CHANGED
|
@@ -106,15 +106,15 @@ var IndexedDbMeta = class {
|
|
|
106
106
|
async update(path, change) {
|
|
107
107
|
const [transaction, store] = this.transaction("readwrite");
|
|
108
108
|
const request2 = store.get(path);
|
|
109
|
-
let
|
|
109
|
+
let next2;
|
|
110
110
|
request2.onsuccess = () => {
|
|
111
|
-
|
|
112
|
-
if (
|
|
111
|
+
next2 = change(request2.result);
|
|
112
|
+
if (next2) store.put(next2);
|
|
113
113
|
else store.delete(path);
|
|
114
114
|
};
|
|
115
115
|
await settle(transaction, () => void 0);
|
|
116
116
|
this.changed({ paths: [path] });
|
|
117
|
-
this.cache.set(path,
|
|
117
|
+
this.cache.set(path, next2 ?? null);
|
|
118
118
|
}
|
|
119
119
|
async move(from, to, root) {
|
|
120
120
|
const [transaction, store] = this.transaction("readwrite");
|
|
@@ -341,8 +341,8 @@ var OpfsFs = class {
|
|
|
341
341
|
resolvePath(base, path) {
|
|
342
342
|
return resolvePath(base, path);
|
|
343
343
|
}
|
|
344
|
-
async walk(parts, from,
|
|
345
|
-
let dir =
|
|
344
|
+
async walk(parts, from, start2) {
|
|
345
|
+
let dir = start2;
|
|
346
346
|
for (let at = from; at < parts.length; at++) {
|
|
347
347
|
dir = await dir.getDirectoryHandle(parts[at]);
|
|
348
348
|
this.dirs.set(`/${parts.slice(0, at + 1).join("/")}`, dir);
|
|
@@ -428,7 +428,7 @@ var OpfsFs = class {
|
|
|
428
428
|
}
|
|
429
429
|
return void 0;
|
|
430
430
|
}
|
|
431
|
-
async locate(path,
|
|
431
|
+
async locate(path, follow2) {
|
|
432
432
|
let current = path;
|
|
433
433
|
for (let hops = 0; hops <= MAX_LINKS; hops++) {
|
|
434
434
|
try {
|
|
@@ -437,9 +437,9 @@ var OpfsFs = class {
|
|
|
437
437
|
if (!missing(err)) throw err;
|
|
438
438
|
const link2 = await this.linkAlong(current);
|
|
439
439
|
if (!link2) throw err;
|
|
440
|
-
if (link2.path === current && !
|
|
441
|
-
const
|
|
442
|
-
current = resolvePath(parentOf2(link2.path), `${link2.link}${
|
|
440
|
+
if (link2.path === current && !follow2) return { path: current, link: link2 };
|
|
441
|
+
const rest2 = current.slice(link2.path.length);
|
|
442
|
+
current = resolvePath(parentOf2(link2.path), `${link2.link}${rest2}`);
|
|
443
443
|
}
|
|
444
444
|
}
|
|
445
445
|
throw fsError("ELOOP", path);
|
|
@@ -755,9 +755,9 @@ var OpfsFs = class {
|
|
|
755
755
|
return timed;
|
|
756
756
|
}
|
|
757
757
|
async restamp(path, timed) {
|
|
758
|
-
for (const
|
|
759
|
-
const mtimeFor = await this.modified(path +
|
|
760
|
-
await this.meta.update(path +
|
|
758
|
+
for (const rest2 of timed) {
|
|
759
|
+
const mtimeFor = await this.modified(path + rest2);
|
|
760
|
+
await this.meta.update(path + rest2, (entry) => entry && { ...entry, mtimeFor });
|
|
761
761
|
}
|
|
762
762
|
}
|
|
763
763
|
async place(handle, dir, name2) {
|
|
@@ -805,8 +805,8 @@ var OpfsFs = class {
|
|
|
805
805
|
}));
|
|
806
806
|
this.touch(parent.path);
|
|
807
807
|
}
|
|
808
|
-
async realpath(path,
|
|
809
|
-
return (await this.locate(path,
|
|
808
|
+
async realpath(path, follow2) {
|
|
809
|
+
return (await this.locate(path, follow2)).path;
|
|
810
810
|
}
|
|
811
811
|
async readlink(path) {
|
|
812
812
|
const found = await this.locate(path, false);
|
|
@@ -1659,8 +1659,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1659
1659
|
async accept(signal, nonblock = false) {
|
|
1660
1660
|
for (; ; ) {
|
|
1661
1661
|
if (this.state !== "listening") throw new KernelError("EINVAL");
|
|
1662
|
-
const
|
|
1663
|
-
if (
|
|
1662
|
+
const next2 = this.queue.shift();
|
|
1663
|
+
if (next2) return next2;
|
|
1664
1664
|
if (nonblock) throw new KernelError("EAGAIN");
|
|
1665
1665
|
await this.changes.wait(signal);
|
|
1666
1666
|
}
|
|
@@ -1841,8 +1841,8 @@ var LoopbackNet = class {
|
|
|
1841
1841
|
if (reserve) this.internal.add(port);
|
|
1842
1842
|
return this.internal.has(port);
|
|
1843
1843
|
}
|
|
1844
|
-
activate(addr,
|
|
1845
|
-
this.activators.set(keyOf(addr),
|
|
1844
|
+
activate(addr, start2) {
|
|
1845
|
+
this.activators.set(keyOf(addr), start2);
|
|
1846
1846
|
}
|
|
1847
1847
|
socket(domain) {
|
|
1848
1848
|
return new KernelSocket(this, domain);
|
|
@@ -2084,12 +2084,12 @@ var MessageQueue = class {
|
|
|
2084
2084
|
}
|
|
2085
2085
|
async *[Symbol.asyncIterator]() {
|
|
2086
2086
|
for (; ; ) {
|
|
2087
|
-
const
|
|
2088
|
-
if (
|
|
2089
|
-
const n = payloadSize(
|
|
2087
|
+
const next2 = this.items.shift();
|
|
2088
|
+
if (next2 !== void 0) {
|
|
2089
|
+
const n = payloadSize(next2);
|
|
2090
2090
|
this.size -= n;
|
|
2091
2091
|
this.taken?.(n);
|
|
2092
|
-
yield
|
|
2092
|
+
yield next2;
|
|
2093
2093
|
continue;
|
|
2094
2094
|
}
|
|
2095
2095
|
if (this.ended) return;
|
|
@@ -2118,7 +2118,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2118
2118
|
...typeof code === "string" ? { code } : {}
|
|
2119
2119
|
});
|
|
2120
2120
|
};
|
|
2121
|
-
const
|
|
2121
|
+
const start2 = async (call) => {
|
|
2122
2122
|
const abort = new AbortController();
|
|
2123
2123
|
const entry = { abort };
|
|
2124
2124
|
open.set(call.nid, entry);
|
|
@@ -2197,9 +2197,9 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2197
2197
|
try {
|
|
2198
2198
|
const messages = socket.messages[Symbol.asyncIterator]();
|
|
2199
2199
|
for (; ; ) {
|
|
2200
|
-
const
|
|
2201
|
-
if (
|
|
2202
|
-
const data =
|
|
2200
|
+
const next2 = await Promise.race([messages.next(), unanswered]);
|
|
2201
|
+
if (next2 === "late" || next2.done) break;
|
|
2202
|
+
const data = next2.value;
|
|
2203
2203
|
if (flow.closing) continue;
|
|
2204
2204
|
if (payloadSize(data) > MESSAGE_LIMIT) {
|
|
2205
2205
|
oversize = true;
|
|
@@ -2240,12 +2240,12 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2240
2240
|
const body = open.get(nid)?.body;
|
|
2241
2241
|
if (!body) return;
|
|
2242
2242
|
try {
|
|
2243
|
-
const
|
|
2244
|
-
if (
|
|
2243
|
+
const next2 = await body.next();
|
|
2244
|
+
if (next2.done) {
|
|
2245
2245
|
open.delete(nid);
|
|
2246
2246
|
peer.postMessage({ net: "end", nid });
|
|
2247
2247
|
} else {
|
|
2248
|
-
const bytes =
|
|
2248
|
+
const bytes = next2.value.slice();
|
|
2249
2249
|
peer.postMessage({ net: "chunk", nid, bytes }, [bytes.buffer]);
|
|
2250
2250
|
}
|
|
2251
2251
|
} catch (e) {
|
|
@@ -2262,7 +2262,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
2262
2262
|
};
|
|
2263
2263
|
return {
|
|
2264
2264
|
answer(call) {
|
|
2265
|
-
if (call.net === "fetch") void
|
|
2265
|
+
if (call.net === "fetch") void start2(call);
|
|
2266
2266
|
else if (call.net === "read") void read(call.nid);
|
|
2267
2267
|
else if (call.net === "ws-open") void openSocket(call);
|
|
2268
2268
|
else if (call.net === "ws-send") void sendOn(call);
|
|
@@ -2290,17 +2290,17 @@ async function realpath(fs, path) {
|
|
|
2290
2290
|
let parts = fs.resolvePath("/", path).split("/").filter(Boolean);
|
|
2291
2291
|
let resolved = "";
|
|
2292
2292
|
for (let hops = 0; parts.length > 0; ) {
|
|
2293
|
-
const [name2, ...
|
|
2294
|
-
const
|
|
2295
|
-
if (!(await fs.lstat(
|
|
2296
|
-
resolved =
|
|
2297
|
-
parts =
|
|
2293
|
+
const [name2, ...rest2] = parts;
|
|
2294
|
+
const next2 = `${resolved}/${name2}`;
|
|
2295
|
+
if (!(await fs.lstat(next2)).isSymbolicLink) {
|
|
2296
|
+
resolved = next2;
|
|
2297
|
+
parts = rest2;
|
|
2298
2298
|
continue;
|
|
2299
2299
|
}
|
|
2300
2300
|
if (++hops > MAX_LINKS2) throw fsError("ELOOP", path);
|
|
2301
|
-
const target = await fs.readlink(
|
|
2301
|
+
const target = await fs.readlink(next2);
|
|
2302
2302
|
const base = target.startsWith("/") ? "/" : resolved || "/";
|
|
2303
|
-
parts = [...fs.resolvePath(base, target).split("/").filter(Boolean), ...
|
|
2303
|
+
parts = [...fs.resolvePath(base, target).split("/").filter(Boolean), ...rest2];
|
|
2304
2304
|
resolved = "";
|
|
2305
2305
|
}
|
|
2306
2306
|
return resolved || "/";
|
|
@@ -2652,10 +2652,10 @@ var Incoming = class {
|
|
|
2652
2652
|
this.eof = true;
|
|
2653
2653
|
return false;
|
|
2654
2654
|
}
|
|
2655
|
-
const
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
this.buf =
|
|
2655
|
+
const next2 = new Uint8Array(this.buf.length + chunk2.length);
|
|
2656
|
+
next2.set(this.buf);
|
|
2657
|
+
next2.set(chunk2, this.buf.length);
|
|
2658
|
+
this.buf = next2;
|
|
2659
2659
|
return true;
|
|
2660
2660
|
}
|
|
2661
2661
|
take(n) {
|
|
@@ -3629,15 +3629,15 @@ var octets = (bytes) => tlv(4, bytes);
|
|
|
3629
3629
|
var bits = (bytes, unused = 0) => tlv(3, Uint8Array.of(unused), bytes);
|
|
3630
3630
|
var TRUE = tlv(1, Uint8Array.of(255));
|
|
3631
3631
|
function integer(magnitude) {
|
|
3632
|
-
let
|
|
3633
|
-
while (
|
|
3634
|
-
const trimmed = magnitude.subarray(
|
|
3632
|
+
let start2 = 0;
|
|
3633
|
+
while (start2 < magnitude.length - 1 && magnitude[start2] === 0) start2++;
|
|
3634
|
+
const trimmed = magnitude.subarray(start2);
|
|
3635
3635
|
return tlv(2, trimmed[0] & 128 ? concat2([Uint8Array.of(0), trimmed]) : trimmed);
|
|
3636
3636
|
}
|
|
3637
3637
|
function oid(dotted) {
|
|
3638
|
-
const [a, b, ...
|
|
3638
|
+
const [a, b, ...rest2] = dotted.split(".").map(Number);
|
|
3639
3639
|
const out = [40 * a + b];
|
|
3640
|
-
for (const arc of
|
|
3640
|
+
for (const arc of rest2) {
|
|
3641
3641
|
const groups = [];
|
|
3642
3642
|
for (let v = arc; ; v = Math.floor(v / 128)) {
|
|
3643
3643
|
groups.unshift(v & 127);
|
|
@@ -3677,19 +3677,19 @@ function children(der) {
|
|
|
3677
3677
|
function header(der, at) {
|
|
3678
3678
|
const tag = der[at];
|
|
3679
3679
|
let len = der[at + 1];
|
|
3680
|
-
let
|
|
3680
|
+
let start2 = at + 2;
|
|
3681
3681
|
if (len & 128) {
|
|
3682
3682
|
const count = len & 127;
|
|
3683
3683
|
len = 0;
|
|
3684
|
-
for (let i = 0; i < count; i++) len = len * 256 + der[
|
|
3685
|
-
|
|
3684
|
+
for (let i = 0; i < count; i++) len = len * 256 + der[start2 + i];
|
|
3685
|
+
start2 += count;
|
|
3686
3686
|
}
|
|
3687
|
-
if (
|
|
3688
|
-
return [tag,
|
|
3687
|
+
if (start2 + len > der.length) throw new Error("truncated DER");
|
|
3688
|
+
return [tag, start2, start2 + len];
|
|
3689
3689
|
}
|
|
3690
3690
|
function contents(element) {
|
|
3691
|
-
const [,
|
|
3692
|
-
return element.subarray(
|
|
3691
|
+
const [, start2, end] = header(element, 0);
|
|
3692
|
+
return element.subarray(start2, end);
|
|
3693
3693
|
}
|
|
3694
3694
|
function publicKeyBits(spki) {
|
|
3695
3695
|
const key = children(spki)[1];
|
|
@@ -5288,6 +5288,53 @@ function withCommandDirs(fs, names) {
|
|
|
5288
5288
|
};
|
|
5289
5289
|
}
|
|
5290
5290
|
|
|
5291
|
+
// src/fs/physical-path.ts
|
|
5292
|
+
var MAX_HOPS = 40;
|
|
5293
|
+
function start(path) {
|
|
5294
|
+
return { done: [], todo: path.split("/").filter((p) => p !== ""), hops: 0 };
|
|
5295
|
+
}
|
|
5296
|
+
function next(walk) {
|
|
5297
|
+
while (walk.todo.length > 0) {
|
|
5298
|
+
const part = walk.todo.shift();
|
|
5299
|
+
if (part === ".") continue;
|
|
5300
|
+
if (part === "..") {
|
|
5301
|
+
walk.done.pop();
|
|
5302
|
+
continue;
|
|
5303
|
+
}
|
|
5304
|
+
return part;
|
|
5305
|
+
}
|
|
5306
|
+
return void 0;
|
|
5307
|
+
}
|
|
5308
|
+
function lexical(path) {
|
|
5309
|
+
const walk = start(path);
|
|
5310
|
+
for (let part = next(walk); part !== void 0; part = next(walk)) walk.done.push(part);
|
|
5311
|
+
return `/${walk.done.join("/")}`;
|
|
5312
|
+
}
|
|
5313
|
+
function rest(walk, part) {
|
|
5314
|
+
return lexical(`/${[...walk.done, part, ...walk.todo].join("/")}`);
|
|
5315
|
+
}
|
|
5316
|
+
function follow(walk, target) {
|
|
5317
|
+
if (++walk.hops > MAX_HOPS) return false;
|
|
5318
|
+
if (target.startsWith("/")) walk.done.length = 0;
|
|
5319
|
+
walk.todo = [...target.split("/").filter((p) => p !== ""), ...walk.todo];
|
|
5320
|
+
return true;
|
|
5321
|
+
}
|
|
5322
|
+
async function physicalPathAsync(fs, path) {
|
|
5323
|
+
const walk = start(path);
|
|
5324
|
+
for (let part = next(walk); part !== void 0; part = next(walk)) {
|
|
5325
|
+
const at = `/${[...walk.done, part].join("/")}`;
|
|
5326
|
+
let target;
|
|
5327
|
+
try {
|
|
5328
|
+
target = (await fs.lstat(at)).isSymbolicLink ? await fs.readlink(at) : void 0;
|
|
5329
|
+
} catch {
|
|
5330
|
+
return rest(walk, part);
|
|
5331
|
+
}
|
|
5332
|
+
if (target === void 0) walk.done.push(part);
|
|
5333
|
+
else if (!follow(walk, target)) return lexical(path);
|
|
5334
|
+
}
|
|
5335
|
+
return `/${walk.done.join("/")}`;
|
|
5336
|
+
}
|
|
5337
|
+
|
|
5291
5338
|
// src/fs/unlinked.ts
|
|
5292
5339
|
var UNLINKED_DIR = ".slicc-unlinked";
|
|
5293
5340
|
function webLocks() {
|
|
@@ -5343,9 +5390,9 @@ var UnlinkedKeeper = class {
|
|
|
5343
5390
|
void locks?.request(lockName(this.instance), () => new Promise(() => void 0));
|
|
5344
5391
|
}
|
|
5345
5392
|
serial(op) {
|
|
5346
|
-
const
|
|
5347
|
-
this.queue =
|
|
5348
|
-
return
|
|
5393
|
+
const next2 = this.queue.then(op);
|
|
5394
|
+
this.queue = next2.catch(() => void 0);
|
|
5395
|
+
return next2;
|
|
5349
5396
|
}
|
|
5350
5397
|
wrap(fs = this.fs) {
|
|
5351
5398
|
const keeper = this;
|
|
@@ -5642,10 +5689,10 @@ var ChildTable = class {
|
|
|
5642
5689
|
}
|
|
5643
5690
|
return this.track(req, fds, captured, this.spawner);
|
|
5644
5691
|
}
|
|
5645
|
-
async track(req, fds, captured,
|
|
5692
|
+
async track(req, fds, captured, start2) {
|
|
5646
5693
|
let handle;
|
|
5647
5694
|
try {
|
|
5648
|
-
handle = await
|
|
5695
|
+
handle = await start2(req, fds);
|
|
5649
5696
|
} catch (e) {
|
|
5650
5697
|
await fds.closeAll();
|
|
5651
5698
|
throw e;
|
|
@@ -5882,8 +5929,7 @@ var HeldSet = class extends Set {
|
|
|
5882
5929
|
delete(holds) {
|
|
5883
5930
|
const removed = super.delete(holds);
|
|
5884
5931
|
for (const path of /* @__PURE__ */ new Set([...holds.keys(), ...holds.opens.keys()])) this.idle(path);
|
|
5885
|
-
|
|
5886
|
-
holds.unlinked.clear();
|
|
5932
|
+
holds.releaseAll();
|
|
5887
5933
|
return removed;
|
|
5888
5934
|
}
|
|
5889
5935
|
};
|
|
@@ -5896,6 +5942,10 @@ var HeldPaths = class extends Map {
|
|
|
5896
5942
|
opens = /* @__PURE__ */ new Map();
|
|
5897
5943
|
unlinked = /* @__PURE__ */ new Map();
|
|
5898
5944
|
aliases = /* @__PURE__ */ new Map();
|
|
5945
|
+
handles = /* @__PURE__ */ new Map();
|
|
5946
|
+
keptHandles = /* @__PURE__ */ new Map();
|
|
5947
|
+
uses = /* @__PURE__ */ new Map();
|
|
5948
|
+
lastHandle = 0;
|
|
5899
5949
|
owning;
|
|
5900
5950
|
onIdle;
|
|
5901
5951
|
keyOf(path) {
|
|
@@ -5911,29 +5961,70 @@ var HeldPaths = class extends Map {
|
|
|
5911
5961
|
return this.opens.keys();
|
|
5912
5962
|
}
|
|
5913
5963
|
isKept(path) {
|
|
5914
|
-
|
|
5964
|
+
const ids = this.handlesAt(path);
|
|
5965
|
+
return ids.length === 0 ? this.unlinked.has(path) : ids.every((id) => this.keptHandles.has(id));
|
|
5966
|
+
}
|
|
5967
|
+
handlesAt(path) {
|
|
5968
|
+
return [...this.handles].filter(([, key]) => key === path).map(([id]) => id);
|
|
5969
|
+
}
|
|
5970
|
+
keptFor(handle) {
|
|
5971
|
+
return this.keptHandles.get(handle);
|
|
5915
5972
|
}
|
|
5916
5973
|
keep(path, file) {
|
|
5974
|
+
const fresh = this.handlesAt(path).filter((id) => !this.keptHandles.has(id));
|
|
5975
|
+
for (const id of fresh) this.keptHandles.set(id, file);
|
|
5976
|
+
this.uses.set(file, Math.max(fresh.length, 1));
|
|
5917
5977
|
this.unlinked.set(path, file);
|
|
5918
5978
|
}
|
|
5919
|
-
unkeep(path) {
|
|
5920
|
-
this.
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
else {
|
|
5929
|
-
this.opens.delete(key);
|
|
5930
|
-
this.unlinked.get(key)?.release();
|
|
5931
|
-
this.unlinked.delete(key);
|
|
5932
|
-
for (const [alias, target] of this.aliases) if (target === key) this.aliases.delete(alias);
|
|
5933
|
-
this.onIdle?.(key);
|
|
5934
|
-
}
|
|
5979
|
+
unkeep(path, file) {
|
|
5980
|
+
for (const [id, kept] of this.keptHandles) if (kept === file) this.keptHandles.delete(id);
|
|
5981
|
+
this.uses.delete(file);
|
|
5982
|
+
if (this.unlinked.get(path) === file) this.unlinked.delete(path);
|
|
5983
|
+
}
|
|
5984
|
+
letGo(file, all = false) {
|
|
5985
|
+
const left = all ? 0 : (this.uses.get(file) ?? 0) - 1;
|
|
5986
|
+
if (left > 0) {
|
|
5987
|
+
this.uses.set(file, left);
|
|
5935
5988
|
return;
|
|
5936
5989
|
}
|
|
5990
|
+
if (!this.uses.delete(file)) return;
|
|
5991
|
+
file.release();
|
|
5992
|
+
for (const [path, kept] of this.unlinked) if (kept === file) this.unlinked.delete(path);
|
|
5993
|
+
}
|
|
5994
|
+
releaseAll() {
|
|
5995
|
+
for (const file of [...this.uses.keys()]) this.letGo(file, true);
|
|
5996
|
+
this.keptHandles.clear();
|
|
5997
|
+
}
|
|
5998
|
+
hold(path, on, open = false, real, handle) {
|
|
5999
|
+
if (open) return this.holdOpen(path, on, real, handle);
|
|
6000
|
+
this.holdWrite(path, on);
|
|
6001
|
+
return void 0;
|
|
6002
|
+
}
|
|
6003
|
+
holdOpen(path, on, real, handle) {
|
|
6004
|
+
const known = handle === void 0 ? void 0 : this.handles.get(handle);
|
|
6005
|
+
const key = known ?? real ?? this.keyOf(path);
|
|
6006
|
+
if (key !== path) this.aliases.set(path, key);
|
|
6007
|
+
if (handle !== void 0) {
|
|
6008
|
+
const kept = this.keptHandles.get(handle);
|
|
6009
|
+
this.handles.delete(handle);
|
|
6010
|
+
this.keptHandles.delete(handle);
|
|
6011
|
+
if (kept) this.letGo(kept);
|
|
6012
|
+
}
|
|
6013
|
+
const count = (this.opens.get(key) ?? 0) + (on ? 1 : -1);
|
|
6014
|
+
if (count > 0) this.opens.set(key, count);
|
|
6015
|
+
else {
|
|
6016
|
+
this.opens.delete(key);
|
|
6017
|
+
for (const id of this.handlesAt(key)) this.handles.delete(id);
|
|
6018
|
+
const kept = this.unlinked.get(key);
|
|
6019
|
+
if (kept) this.letGo(kept, true);
|
|
6020
|
+
for (const [alias, target] of this.aliases) if (target === key) this.aliases.delete(alias);
|
|
6021
|
+
this.onIdle?.(key);
|
|
6022
|
+
}
|
|
6023
|
+
if (!on) return void 0;
|
|
6024
|
+
this.handles.set(++this.lastHandle, key);
|
|
6025
|
+
return this.lastHandle;
|
|
6026
|
+
}
|
|
6027
|
+
holdWrite(path, on) {
|
|
5937
6028
|
const count = (this.get(path) ?? 0) + (on ? 1 : -1);
|
|
5938
6029
|
if (count > 0) this.set(path, count);
|
|
5939
6030
|
else {
|
|
@@ -5970,6 +6061,9 @@ var HeldPaths = class extends Map {
|
|
|
5970
6061
|
this.opens.delete(path);
|
|
5971
6062
|
this.opens.set(moved2, (this.opens.get(moved2) ?? 0) + count);
|
|
5972
6063
|
}
|
|
6064
|
+
for (const [id, key] of this.handles) {
|
|
6065
|
+
if (within4(key, from)) this.handles.set(id, to + key.slice(from.length));
|
|
6066
|
+
}
|
|
5973
6067
|
}
|
|
5974
6068
|
isRevoked(path) {
|
|
5975
6069
|
return this.revoked.has(path);
|
|
@@ -6644,9 +6738,9 @@ var MountFs = class {
|
|
|
6644
6738
|
this.table.forget(found.mount, normalizePath(path));
|
|
6645
6739
|
await found.mount.conn.call({ op: "symlink", target, path: found.rel });
|
|
6646
6740
|
}
|
|
6647
|
-
async realpath(path,
|
|
6741
|
+
async realpath(path, follow2) {
|
|
6648
6742
|
if (this.at(path) || !this.base.realpath) throw errnoError("ENOSYS", path);
|
|
6649
|
-
const real = await this.base.realpath(path,
|
|
6743
|
+
const real = await this.base.realpath(path, follow2);
|
|
6650
6744
|
if (this.at(real)) throw errnoError("ENOSYS", path);
|
|
6651
6745
|
return real;
|
|
6652
6746
|
}
|
|
@@ -6833,25 +6927,31 @@ async function ranged(fs, path, req) {
|
|
|
6833
6927
|
}
|
|
6834
6928
|
var UNLINKED_OPS = /* @__PURE__ */ new Set(["read", "pread", "pwrite", "truncate"]);
|
|
6835
6929
|
var OWN_OPS = /* @__PURE__ */ new Set(["rm", "unlink", "rmdir", "rename"]);
|
|
6930
|
+
async function keptOr(entry, path, handle) {
|
|
6931
|
+
if (handle !== void 0) return entry.keptFor?.(handle)?.hidden ?? path;
|
|
6932
|
+
const kept = entry.unlinked?.(path);
|
|
6933
|
+
return kept && !await entry.fs.exists(path) ? kept.hidden : path;
|
|
6934
|
+
}
|
|
6836
6935
|
async function dispatchSyncFs(req) {
|
|
6837
6936
|
const entry = resolveSyncFsToken(req.token);
|
|
6838
6937
|
if (!entry) return { ok: false, errno: "EACCES", message: "sync-fs: unknown or revoked token" };
|
|
6839
6938
|
const { fs, cwd } = entry;
|
|
6840
6939
|
try {
|
|
6841
6940
|
const path = fs.resolvePath(cwd, req.path);
|
|
6941
|
+
if (req.op === "kept") return json2(entry.keptFor?.(req.handle ?? -1) !== void 0);
|
|
6842
6942
|
if (req.op === "statfs") return json2(await entry.statfs?.(path) ?? await storageUsage());
|
|
6843
6943
|
if (req.op === "hold") {
|
|
6844
6944
|
const [on, open] = [((req.mode ?? 0) & 1) === 1, ((req.mode ?? 0) & 2) === 2];
|
|
6845
|
-
|
|
6846
|
-
|
|
6945
|
+
if (on && open) {
|
|
6946
|
+
const real = await fs.realpath?.(path, true).catch(() => path);
|
|
6947
|
+
return json2(entry.hold?.(path, on, open, real) ?? null);
|
|
6948
|
+
}
|
|
6949
|
+
entry.hold?.(path, on, open, void 0, req.handle);
|
|
6847
6950
|
return done;
|
|
6848
6951
|
}
|
|
6849
6952
|
if (entry.revoked?.(path)) return { ok: false, errno: "EIO", message: `${path} was unmounted` };
|
|
6850
6953
|
if (req.op === "write" && req.mode === 1 || UNLINKED_OPS.has(req.op)) {
|
|
6851
|
-
const serve = async () =>
|
|
6852
|
-
const kept = entry.unlinked?.(path);
|
|
6853
|
-
return run(entry, kept && !await fs.exists(path) ? kept.hidden : path, req);
|
|
6854
|
-
};
|
|
6954
|
+
const serve = async () => run(entry, await keptOr(entry, path, req.handle), req);
|
|
6855
6955
|
return await (entry.gate ? entry.gate(path, serve) : serve());
|
|
6856
6956
|
}
|
|
6857
6957
|
if (!entry.own || !OWN_OPS.has(req.op)) return await run(entry, path, req);
|
|
@@ -7210,9 +7310,9 @@ var HttpHandles = class {
|
|
|
7210
7310
|
return this.close(req.handle);
|
|
7211
7311
|
}
|
|
7212
7312
|
traits() {
|
|
7213
|
-
const { unavailable, crossOrigin = "any", ...
|
|
7313
|
+
const { unavailable, crossOrigin = "any", ...rest2 } = this.transport.traits;
|
|
7214
7314
|
if (unavailable) return { ok: false, errno: "ENETUNREACH", message: NO_TRANSPORT };
|
|
7215
|
-
return { ok: true, kind: "json", json: { ...
|
|
7315
|
+
return { ok: true, kind: "json", json: { ...rest2, crossOrigin } };
|
|
7216
7316
|
}
|
|
7217
7317
|
add(abort, body, cancel) {
|
|
7218
7318
|
const handle = ++this.nextHandle;
|
|
@@ -7274,9 +7374,9 @@ var HttpHandles = class {
|
|
|
7274
7374
|
async take(entry, max) {
|
|
7275
7375
|
if (entry.left.length === 0 && !entry.done) {
|
|
7276
7376
|
try {
|
|
7277
|
-
const
|
|
7278
|
-
if (
|
|
7279
|
-
else entry.left =
|
|
7377
|
+
const next2 = await entry.body.next();
|
|
7378
|
+
if (next2.done) entry.done = true;
|
|
7379
|
+
else entry.left = next2.value;
|
|
7280
7380
|
} catch (e) {
|
|
7281
7381
|
entry.done = true;
|
|
7282
7382
|
const timedOut = e?.code === "ETIMEDOUT";
|
|
@@ -7638,12 +7738,12 @@ var KernelTty = class {
|
|
|
7638
7738
|
const chunks = [];
|
|
7639
7739
|
let n = 0;
|
|
7640
7740
|
while (this.readable.length > 0 && n < max) {
|
|
7641
|
-
const
|
|
7642
|
-
if (
|
|
7643
|
-
const take =
|
|
7741
|
+
const next2 = this.readable[0];
|
|
7742
|
+
if (next2 === null || next2 === void 0) break;
|
|
7743
|
+
const take = next2.subarray(0, max - n);
|
|
7644
7744
|
chunks.push(take);
|
|
7645
7745
|
n += take.length;
|
|
7646
|
-
if (take.length <
|
|
7746
|
+
if (take.length < next2.length) this.readable[0] = next2.subarray(take.length);
|
|
7647
7747
|
else this.readable.shift();
|
|
7648
7748
|
if (this.canonical) break;
|
|
7649
7749
|
}
|
|
@@ -7740,11 +7840,11 @@ var PtyPair = class {
|
|
|
7740
7840
|
const chunks = [];
|
|
7741
7841
|
let n = 0;
|
|
7742
7842
|
while (this.queue.length > 0 && n < max - status) {
|
|
7743
|
-
const
|
|
7744
|
-
const take =
|
|
7843
|
+
const next2 = this.queue[0];
|
|
7844
|
+
const take = next2.subarray(0, max - status - n);
|
|
7745
7845
|
chunks.push(take);
|
|
7746
7846
|
n += take.length;
|
|
7747
|
-
if (take.length <
|
|
7847
|
+
if (take.length < next2.length) this.queue[0] = next2.subarray(take.length);
|
|
7748
7848
|
else this.queue.shift();
|
|
7749
7849
|
}
|
|
7750
7850
|
const out = new Uint8Array(status + n);
|
|
@@ -8050,7 +8150,7 @@ var Pages = class {
|
|
|
8050
8150
|
}
|
|
8051
8151
|
const last = runs[runs.length - 1];
|
|
8052
8152
|
if (last) last[1] = Math.max(last[1], Math.min(READAHEAD, this.stored - last[0]));
|
|
8053
|
-
return runs.map(([
|
|
8153
|
+
return runs.map(([start2, n]) => [start2, Math.min(n, this.stored - start2)]);
|
|
8054
8154
|
}
|
|
8055
8155
|
partial(at, length2) {
|
|
8056
8156
|
if (length2 === 0) return [];
|
|
@@ -8058,16 +8158,16 @@ var Pages = class {
|
|
|
8058
8158
|
const edges = /* @__PURE__ */ new Set([Math.floor(at / PAGE), Math.floor((at + length2 - 1) / PAGE)]);
|
|
8059
8159
|
const runs = [];
|
|
8060
8160
|
for (const page of edges) {
|
|
8061
|
-
const
|
|
8062
|
-
const covered = at <=
|
|
8063
|
-
if (covered || this.pages.has(page) ||
|
|
8064
|
-
runs.push([
|
|
8161
|
+
const start2 = page * PAGE;
|
|
8162
|
+
const covered = at <= start2 && at + length2 >= start2 + PAGE;
|
|
8163
|
+
if (covered || this.pages.has(page) || start2 >= this.stored) continue;
|
|
8164
|
+
runs.push([start2, Math.min(PAGE, this.stored - start2)]);
|
|
8065
8165
|
}
|
|
8066
8166
|
return runs;
|
|
8067
8167
|
}
|
|
8068
|
-
fill(
|
|
8168
|
+
fill(start2, bytes) {
|
|
8069
8169
|
for (let at = 0; at < bytes.length; at += PAGE) {
|
|
8070
|
-
const page = (
|
|
8170
|
+
const page = (start2 + at) / PAGE;
|
|
8071
8171
|
if (this.pages.has(page)) continue;
|
|
8072
8172
|
const part = bytes.subarray(at, Math.min(at + PAGE, bytes.length));
|
|
8073
8173
|
const fresh = this.take(part.length);
|
|
@@ -8133,14 +8233,14 @@ var Pages = class {
|
|
|
8133
8233
|
while (j < sorted.length && sorted[j] === first + (j - i) && sorted[j] * PAGE % RUN !== 0) {
|
|
8134
8234
|
j++;
|
|
8135
8235
|
}
|
|
8136
|
-
const
|
|
8236
|
+
const start2 = first * PAGE;
|
|
8137
8237
|
const end = Math.min(this.length, (first + (j - i)) * PAGE);
|
|
8138
|
-
const bytes = new Uint8Array(end -
|
|
8238
|
+
const bytes = new Uint8Array(end - start2);
|
|
8139
8239
|
for (let k = i; k < j; k++) {
|
|
8140
8240
|
const page = this.pages.get(sorted[k]);
|
|
8141
|
-
bytes.set(page.subarray(0, Math.min(PAGE, end - (k - i) * PAGE -
|
|
8241
|
+
bytes.set(page.subarray(0, Math.min(PAGE, end - (k - i) * PAGE - start2)), (k - i) * PAGE);
|
|
8142
8242
|
}
|
|
8143
|
-
runs.push({ offset:
|
|
8243
|
+
runs.push({ offset: start2, bytes });
|
|
8144
8244
|
i = j;
|
|
8145
8245
|
}
|
|
8146
8246
|
const written2 = Math.max(this.stored, ...runs.map((r) => r.offset + r.bytes.length));
|
|
@@ -8207,8 +8307,8 @@ var AsyncRangedFile = class {
|
|
|
8207
8307
|
return this.pages.length;
|
|
8208
8308
|
}
|
|
8209
8309
|
async fetch(runs) {
|
|
8210
|
-
for (const [
|
|
8211
|
-
this.pages.fill(
|
|
8310
|
+
for (const [start2, n] of runs) {
|
|
8311
|
+
this.pages.fill(start2, await this.io.pread(this.path, start2, n, this.version));
|
|
8212
8312
|
}
|
|
8213
8313
|
}
|
|
8214
8314
|
async read(at, length2) {
|
|
@@ -8283,9 +8383,9 @@ var VfsNode = class {
|
|
|
8283
8383
|
if (dirty && contents2 !== void 0) this.markDirty();
|
|
8284
8384
|
}
|
|
8285
8385
|
serial(op) {
|
|
8286
|
-
const
|
|
8287
|
-
this.queue =
|
|
8288
|
-
return
|
|
8386
|
+
const next2 = this.queue.then(op);
|
|
8387
|
+
this.queue = next2.catch(() => void 0);
|
|
8388
|
+
return next2;
|
|
8289
8389
|
}
|
|
8290
8390
|
revoke() {
|
|
8291
8391
|
this.revoked = true;
|
|
@@ -8467,10 +8567,10 @@ var VfsNodes = class {
|
|
|
8467
8567
|
targetKey(path) {
|
|
8468
8568
|
return this.real(path, true, () => realTarget(this.fs, path));
|
|
8469
8569
|
}
|
|
8470
|
-
async real(path,
|
|
8570
|
+
async real(path, follow2, walk) {
|
|
8471
8571
|
if (this.fs.realpath) {
|
|
8472
8572
|
try {
|
|
8473
|
-
return await this.fs.realpath(path,
|
|
8573
|
+
return await this.fs.realpath(path, follow2);
|
|
8474
8574
|
} catch (err) {
|
|
8475
8575
|
if (errCode(err) === "ELOOP") throw err;
|
|
8476
8576
|
}
|
|
@@ -8598,8 +8698,8 @@ var VfsNodes = class {
|
|
|
8598
8698
|
}
|
|
8599
8699
|
}
|
|
8600
8700
|
};
|
|
8601
|
-
async function present(fs, path,
|
|
8602
|
-
const look = (
|
|
8701
|
+
async function present(fs, path, follow2 = false) {
|
|
8702
|
+
const look = (follow2 ? void 0 : fs.lstat) ?? fs.stat;
|
|
8603
8703
|
try {
|
|
8604
8704
|
await (look ? look.call(fs, path) : fs.readFileBuffer(path));
|
|
8605
8705
|
return true;
|
|
@@ -8625,10 +8725,10 @@ async function realDir(fs, dir, budget = { hops: 0 }) {
|
|
|
8625
8725
|
at = parentOf6(at);
|
|
8626
8726
|
continue;
|
|
8627
8727
|
}
|
|
8628
|
-
const
|
|
8629
|
-
const link2 = await linkOf(fs,
|
|
8728
|
+
const next2 = at === "/" ? `/${part}` : `${at}/${part}`;
|
|
8729
|
+
const link2 = await linkOf(fs, next2);
|
|
8630
8730
|
if (link2 === void 0) {
|
|
8631
|
-
at =
|
|
8731
|
+
at = next2;
|
|
8632
8732
|
continue;
|
|
8633
8733
|
}
|
|
8634
8734
|
if (budget.hops >= MAX_LINKS5) throw fsError("ELOOP", dir);
|
|
@@ -9623,7 +9723,8 @@ function holdingToken(opts, holds) {
|
|
|
9623
9723
|
fs: opts.fs,
|
|
9624
9724
|
cwd: opts.cwd,
|
|
9625
9725
|
...opts.statfs ? { statfs: opts.statfs } : {},
|
|
9626
|
-
hold: (path, on, open, real) => holds.hold(path, on, open, real),
|
|
9726
|
+
hold: (path, on, open, real, handle) => holds.hold(path, on, open, real, handle),
|
|
9727
|
+
keptFor: (handle) => holds.keptFor(handle),
|
|
9627
9728
|
unlinked: (path) => holds.keptAt(path),
|
|
9628
9729
|
gate: (path, op) => opts.unlinkGate && holds.holding(path) ? opts.unlinkGate.run(holds.keyOf(path), op) : op(),
|
|
9629
9730
|
own: (path, op) => holds.own(path, op),
|
|
@@ -10880,9 +10981,9 @@ function tmpfs() {
|
|
|
10880
10981
|
let node = root;
|
|
10881
10982
|
for (const name2 of parts(path)) {
|
|
10882
10983
|
if (node.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
10883
|
-
const
|
|
10884
|
-
if (!
|
|
10885
|
-
node =
|
|
10984
|
+
const next2 = node.children.get(name2);
|
|
10985
|
+
if (!next2) throw fsError2("ENOENT", path);
|
|
10986
|
+
node = next2;
|
|
10886
10987
|
}
|
|
10887
10988
|
return node;
|
|
10888
10989
|
}
|
|
@@ -11446,8 +11547,8 @@ var Launcher = class {
|
|
|
11446
11547
|
const words = shebang(head) ?? (binfmt ? [binfmt] : void 0);
|
|
11447
11548
|
if (!words) return void 0;
|
|
11448
11549
|
if (baseName(words[0]) === "env") words.shift();
|
|
11449
|
-
const [interp, ...
|
|
11450
|
-
const arg =
|
|
11550
|
+
const [interp, ...rest2] = words;
|
|
11551
|
+
const arg = rest2.join(" ");
|
|
11451
11552
|
const passed = [...arg ? [arg] : [], command ? script : file, ...argv.slice(1)];
|
|
11452
11553
|
const found = interp ? await this.resolve(interp, interp, cwd) : void 0;
|
|
11453
11554
|
if (!found) {
|
|
@@ -11528,7 +11629,8 @@ var Launcher = class {
|
|
|
11528
11629
|
}
|
|
11529
11630
|
async launch(planned, req) {
|
|
11530
11631
|
const { target, args } = planned;
|
|
11531
|
-
const
|
|
11632
|
+
const cwd = await physicalPathAsync(this.base, req.cwd);
|
|
11633
|
+
const seen = { ...req.env, HOSTNAME: this.hostname, cwd };
|
|
11532
11634
|
const env = { ...expandDefaults(target.env, seen), ...req.env };
|
|
11533
11635
|
for (const key of target.unset ?? []) delete env[key];
|
|
11534
11636
|
env.HOSTNAME = this.hostname;
|
|
@@ -11539,7 +11641,7 @@ var Launcher = class {
|
|
|
11539
11641
|
await req.fds.closeAll();
|
|
11540
11642
|
throw err;
|
|
11541
11643
|
}
|
|
11542
|
-
return this.start({ ...req, program, argv0: target.argv0, args, env });
|
|
11644
|
+
return this.start({ ...req, cwd, program, argv0: target.argv0, args, env });
|
|
11543
11645
|
}
|
|
11544
11646
|
groupSession(pgid) {
|
|
11545
11647
|
return this.jobs.sessionOf(pgid);
|
|
@@ -11946,7 +12048,8 @@ var Launcher = class {
|
|
|
11946
12048
|
async starting(argv, dir) {
|
|
11947
12049
|
this.catalog = void 0;
|
|
11948
12050
|
this.binfmts = void 0;
|
|
11949
|
-
const
|
|
12051
|
+
const start2 = dir ?? "/";
|
|
12052
|
+
const cwd = await physicalPathAsync(this.base, start2.startsWith("/") ? start2 : `/${start2}`);
|
|
11950
12053
|
const [file = ""] = argv;
|
|
11951
12054
|
await this.base.mkdir(cwd, { recursive: true });
|
|
11952
12055
|
return { cwd, file, planned: await this.plan(file, argv, cwd) };
|