@ai-ecoverse/slicc-kernel 1.40.1 → 1.41.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 +1 -1
- package/dist/kernel-worker.js +153 -104
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +110 -39
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +175 -126
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +110 -39
- package/dist/process-worker.js.map +4 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -174,7 +174,7 @@ On top of preview1 a WASI program gets:
|
|
|
174
174
|
|
|
175
175
|
- **Threads**: `wasi.thread-spawn` (wasm32-wasip1-threads) and WASIX `thread_spawn_v2` start a worker per thread on the process's shared memory, sized from the module's own import (a 2 GiB maximum when the engine cannot reserve more). The threads share one descriptor table; `exit` or a trap in any thread ends the process. At most 64 threads per process; `SLICC_WASM_THREADS` sets another cap, up to 256.
|
|
176
176
|
- **WASIX** (a module importing `wasix_32v1`): fork and setjmp/longjmp through Asyncify (the module is built with `wasm-opt --asyncify`), exec, `posix_spawn`, `waitpid`, pipes, `dup2`, signal handlers and interval timers, terminal modes, and dynamic linking: a position-independent main module loads side modules with `dlopen` from `LD_LIBRARY_PATH`, its runtime path, `/lib`, `/usr/lib` and `/usr/local/lib`.
|
|
177
|
-
- **Sockets**: the WASIX socket calls (`sock_open`, `bind`, `listen`, `connect`, `accept`, options, local and peer names) are the kernel's loopback sockets, and preview1's `sock_recv` / `sock_send` / `sock_shutdown` work on them and on inherited ones. Writing to a socket whose peer is gone fails with `EPIPE`, through `fd_write` as through `sock_send`, as if `MSG_NOSIGNAL` were set, since a WASI program cannot ignore `SIGPIPE`; a pipe or terminal whose reader is gone still ends the program with status 141. HTTP and HTTPS leave through the realm proxy that `https_proxy` names, as for any other program; `resolve` answers `/etc/hosts` names and literal addresses, and the [uplink](#uplink)'s names.
|
|
177
|
+
- **Sockets**: the WASIX socket calls (`sock_open`, `sock_pair` for an `AF_UNIX` stream pair, `bind`, `listen`, `connect`, `accept`, options, local and peer names) are the kernel's loopback sockets, and preview1's `sock_recv` / `sock_send` / `sock_shutdown` work on them and on inherited ones. Writing to a socket whose peer is gone fails with `EPIPE`, through `fd_write` as through `sock_send`, as if `MSG_NOSIGNAL` were set, since a WASI program cannot ignore `SIGPIPE`; a pipe or terminal whose reader is gone still ends the program with status 141. HTTP and HTTPS leave through the realm proxy that `https_proxy` names, as for any other program; `resolve` answers `/etc/hosts` names and literal addresses, and the [uplink](#uplink)'s names.
|
|
178
178
|
- **Diagnostics**: a trap ends the program with 134 and its message on stderr; with `SLICC_WASM_BACKTRACE=1` the wasm frames follow, named from the module's name section, or from a sidecar for a module shipped without one (`<module>.names` beside it, or the same path in a `<package>-names` package). `SLICC_WASI_STATS=1` makes a program print its calls, counted and timed, as it ends.
|
|
179
179
|
|
|
180
180
|
### Program imports
|
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;
|
|
@@ -6644,9 +6691,9 @@ var MountFs = class {
|
|
|
6644
6691
|
this.table.forget(found.mount, normalizePath(path));
|
|
6645
6692
|
await found.mount.conn.call({ op: "symlink", target, path: found.rel });
|
|
6646
6693
|
}
|
|
6647
|
-
async realpath(path,
|
|
6694
|
+
async realpath(path, follow2) {
|
|
6648
6695
|
if (this.at(path) || !this.base.realpath) throw errnoError("ENOSYS", path);
|
|
6649
|
-
const real = await this.base.realpath(path,
|
|
6696
|
+
const real = await this.base.realpath(path, follow2);
|
|
6650
6697
|
if (this.at(real)) throw errnoError("ENOSYS", path);
|
|
6651
6698
|
return real;
|
|
6652
6699
|
}
|
|
@@ -7210,9 +7257,9 @@ var HttpHandles = class {
|
|
|
7210
7257
|
return this.close(req.handle);
|
|
7211
7258
|
}
|
|
7212
7259
|
traits() {
|
|
7213
|
-
const { unavailable, crossOrigin = "any", ...
|
|
7260
|
+
const { unavailable, crossOrigin = "any", ...rest2 } = this.transport.traits;
|
|
7214
7261
|
if (unavailable) return { ok: false, errno: "ENETUNREACH", message: NO_TRANSPORT };
|
|
7215
|
-
return { ok: true, kind: "json", json: { ...
|
|
7262
|
+
return { ok: true, kind: "json", json: { ...rest2, crossOrigin } };
|
|
7216
7263
|
}
|
|
7217
7264
|
add(abort, body, cancel) {
|
|
7218
7265
|
const handle = ++this.nextHandle;
|
|
@@ -7274,9 +7321,9 @@ var HttpHandles = class {
|
|
|
7274
7321
|
async take(entry, max) {
|
|
7275
7322
|
if (entry.left.length === 0 && !entry.done) {
|
|
7276
7323
|
try {
|
|
7277
|
-
const
|
|
7278
|
-
if (
|
|
7279
|
-
else entry.left =
|
|
7324
|
+
const next2 = await entry.body.next();
|
|
7325
|
+
if (next2.done) entry.done = true;
|
|
7326
|
+
else entry.left = next2.value;
|
|
7280
7327
|
} catch (e) {
|
|
7281
7328
|
entry.done = true;
|
|
7282
7329
|
const timedOut = e?.code === "ETIMEDOUT";
|
|
@@ -7638,12 +7685,12 @@ var KernelTty = class {
|
|
|
7638
7685
|
const chunks = [];
|
|
7639
7686
|
let n = 0;
|
|
7640
7687
|
while (this.readable.length > 0 && n < max) {
|
|
7641
|
-
const
|
|
7642
|
-
if (
|
|
7643
|
-
const take =
|
|
7688
|
+
const next2 = this.readable[0];
|
|
7689
|
+
if (next2 === null || next2 === void 0) break;
|
|
7690
|
+
const take = next2.subarray(0, max - n);
|
|
7644
7691
|
chunks.push(take);
|
|
7645
7692
|
n += take.length;
|
|
7646
|
-
if (take.length <
|
|
7693
|
+
if (take.length < next2.length) this.readable[0] = next2.subarray(take.length);
|
|
7647
7694
|
else this.readable.shift();
|
|
7648
7695
|
if (this.canonical) break;
|
|
7649
7696
|
}
|
|
@@ -7740,11 +7787,11 @@ var PtyPair = class {
|
|
|
7740
7787
|
const chunks = [];
|
|
7741
7788
|
let n = 0;
|
|
7742
7789
|
while (this.queue.length > 0 && n < max - status) {
|
|
7743
|
-
const
|
|
7744
|
-
const take =
|
|
7790
|
+
const next2 = this.queue[0];
|
|
7791
|
+
const take = next2.subarray(0, max - status - n);
|
|
7745
7792
|
chunks.push(take);
|
|
7746
7793
|
n += take.length;
|
|
7747
|
-
if (take.length <
|
|
7794
|
+
if (take.length < next2.length) this.queue[0] = next2.subarray(take.length);
|
|
7748
7795
|
else this.queue.shift();
|
|
7749
7796
|
}
|
|
7750
7797
|
const out = new Uint8Array(status + n);
|
|
@@ -8050,7 +8097,7 @@ var Pages = class {
|
|
|
8050
8097
|
}
|
|
8051
8098
|
const last = runs[runs.length - 1];
|
|
8052
8099
|
if (last) last[1] = Math.max(last[1], Math.min(READAHEAD, this.stored - last[0]));
|
|
8053
|
-
return runs.map(([
|
|
8100
|
+
return runs.map(([start2, n]) => [start2, Math.min(n, this.stored - start2)]);
|
|
8054
8101
|
}
|
|
8055
8102
|
partial(at, length2) {
|
|
8056
8103
|
if (length2 === 0) return [];
|
|
@@ -8058,16 +8105,16 @@ var Pages = class {
|
|
|
8058
8105
|
const edges = /* @__PURE__ */ new Set([Math.floor(at / PAGE), Math.floor((at + length2 - 1) / PAGE)]);
|
|
8059
8106
|
const runs = [];
|
|
8060
8107
|
for (const page of edges) {
|
|
8061
|
-
const
|
|
8062
|
-
const covered = at <=
|
|
8063
|
-
if (covered || this.pages.has(page) ||
|
|
8064
|
-
runs.push([
|
|
8108
|
+
const start2 = page * PAGE;
|
|
8109
|
+
const covered = at <= start2 && at + length2 >= start2 + PAGE;
|
|
8110
|
+
if (covered || this.pages.has(page) || start2 >= this.stored) continue;
|
|
8111
|
+
runs.push([start2, Math.min(PAGE, this.stored - start2)]);
|
|
8065
8112
|
}
|
|
8066
8113
|
return runs;
|
|
8067
8114
|
}
|
|
8068
|
-
fill(
|
|
8115
|
+
fill(start2, bytes) {
|
|
8069
8116
|
for (let at = 0; at < bytes.length; at += PAGE) {
|
|
8070
|
-
const page = (
|
|
8117
|
+
const page = (start2 + at) / PAGE;
|
|
8071
8118
|
if (this.pages.has(page)) continue;
|
|
8072
8119
|
const part = bytes.subarray(at, Math.min(at + PAGE, bytes.length));
|
|
8073
8120
|
const fresh = this.take(part.length);
|
|
@@ -8133,14 +8180,14 @@ var Pages = class {
|
|
|
8133
8180
|
while (j < sorted.length && sorted[j] === first + (j - i) && sorted[j] * PAGE % RUN !== 0) {
|
|
8134
8181
|
j++;
|
|
8135
8182
|
}
|
|
8136
|
-
const
|
|
8183
|
+
const start2 = first * PAGE;
|
|
8137
8184
|
const end = Math.min(this.length, (first + (j - i)) * PAGE);
|
|
8138
|
-
const bytes = new Uint8Array(end -
|
|
8185
|
+
const bytes = new Uint8Array(end - start2);
|
|
8139
8186
|
for (let k = i; k < j; k++) {
|
|
8140
8187
|
const page = this.pages.get(sorted[k]);
|
|
8141
|
-
bytes.set(page.subarray(0, Math.min(PAGE, end - (k - i) * PAGE -
|
|
8188
|
+
bytes.set(page.subarray(0, Math.min(PAGE, end - (k - i) * PAGE - start2)), (k - i) * PAGE);
|
|
8142
8189
|
}
|
|
8143
|
-
runs.push({ offset:
|
|
8190
|
+
runs.push({ offset: start2, bytes });
|
|
8144
8191
|
i = j;
|
|
8145
8192
|
}
|
|
8146
8193
|
const written2 = Math.max(this.stored, ...runs.map((r) => r.offset + r.bytes.length));
|
|
@@ -8207,8 +8254,8 @@ var AsyncRangedFile = class {
|
|
|
8207
8254
|
return this.pages.length;
|
|
8208
8255
|
}
|
|
8209
8256
|
async fetch(runs) {
|
|
8210
|
-
for (const [
|
|
8211
|
-
this.pages.fill(
|
|
8257
|
+
for (const [start2, n] of runs) {
|
|
8258
|
+
this.pages.fill(start2, await this.io.pread(this.path, start2, n, this.version));
|
|
8212
8259
|
}
|
|
8213
8260
|
}
|
|
8214
8261
|
async read(at, length2) {
|
|
@@ -8283,9 +8330,9 @@ var VfsNode = class {
|
|
|
8283
8330
|
if (dirty && contents2 !== void 0) this.markDirty();
|
|
8284
8331
|
}
|
|
8285
8332
|
serial(op) {
|
|
8286
|
-
const
|
|
8287
|
-
this.queue =
|
|
8288
|
-
return
|
|
8333
|
+
const next2 = this.queue.then(op);
|
|
8334
|
+
this.queue = next2.catch(() => void 0);
|
|
8335
|
+
return next2;
|
|
8289
8336
|
}
|
|
8290
8337
|
revoke() {
|
|
8291
8338
|
this.revoked = true;
|
|
@@ -8467,10 +8514,10 @@ var VfsNodes = class {
|
|
|
8467
8514
|
targetKey(path) {
|
|
8468
8515
|
return this.real(path, true, () => realTarget(this.fs, path));
|
|
8469
8516
|
}
|
|
8470
|
-
async real(path,
|
|
8517
|
+
async real(path, follow2, walk) {
|
|
8471
8518
|
if (this.fs.realpath) {
|
|
8472
8519
|
try {
|
|
8473
|
-
return await this.fs.realpath(path,
|
|
8520
|
+
return await this.fs.realpath(path, follow2);
|
|
8474
8521
|
} catch (err) {
|
|
8475
8522
|
if (errCode(err) === "ELOOP") throw err;
|
|
8476
8523
|
}
|
|
@@ -8598,8 +8645,8 @@ var VfsNodes = class {
|
|
|
8598
8645
|
}
|
|
8599
8646
|
}
|
|
8600
8647
|
};
|
|
8601
|
-
async function present(fs, path,
|
|
8602
|
-
const look = (
|
|
8648
|
+
async function present(fs, path, follow2 = false) {
|
|
8649
|
+
const look = (follow2 ? void 0 : fs.lstat) ?? fs.stat;
|
|
8603
8650
|
try {
|
|
8604
8651
|
await (look ? look.call(fs, path) : fs.readFileBuffer(path));
|
|
8605
8652
|
return true;
|
|
@@ -8625,10 +8672,10 @@ async function realDir(fs, dir, budget = { hops: 0 }) {
|
|
|
8625
8672
|
at = parentOf6(at);
|
|
8626
8673
|
continue;
|
|
8627
8674
|
}
|
|
8628
|
-
const
|
|
8629
|
-
const link2 = await linkOf(fs,
|
|
8675
|
+
const next2 = at === "/" ? `/${part}` : `${at}/${part}`;
|
|
8676
|
+
const link2 = await linkOf(fs, next2);
|
|
8630
8677
|
if (link2 === void 0) {
|
|
8631
|
-
at =
|
|
8678
|
+
at = next2;
|
|
8632
8679
|
continue;
|
|
8633
8680
|
}
|
|
8634
8681
|
if (budget.hops >= MAX_LINKS5) throw fsError("ELOOP", dir);
|
|
@@ -10880,9 +10927,9 @@ function tmpfs() {
|
|
|
10880
10927
|
let node = root;
|
|
10881
10928
|
for (const name2 of parts(path)) {
|
|
10882
10929
|
if (node.kind !== "directory") throw fsError2("ENOTDIR", path);
|
|
10883
|
-
const
|
|
10884
|
-
if (!
|
|
10885
|
-
node =
|
|
10930
|
+
const next2 = node.children.get(name2);
|
|
10931
|
+
if (!next2) throw fsError2("ENOENT", path);
|
|
10932
|
+
node = next2;
|
|
10886
10933
|
}
|
|
10887
10934
|
return node;
|
|
10888
10935
|
}
|
|
@@ -11446,8 +11493,8 @@ var Launcher = class {
|
|
|
11446
11493
|
const words = shebang(head) ?? (binfmt ? [binfmt] : void 0);
|
|
11447
11494
|
if (!words) return void 0;
|
|
11448
11495
|
if (baseName(words[0]) === "env") words.shift();
|
|
11449
|
-
const [interp, ...
|
|
11450
|
-
const arg =
|
|
11496
|
+
const [interp, ...rest2] = words;
|
|
11497
|
+
const arg = rest2.join(" ");
|
|
11451
11498
|
const passed = [...arg ? [arg] : [], command ? script : file, ...argv.slice(1)];
|
|
11452
11499
|
const found = interp ? await this.resolve(interp, interp, cwd) : void 0;
|
|
11453
11500
|
if (!found) {
|
|
@@ -11528,7 +11575,8 @@ var Launcher = class {
|
|
|
11528
11575
|
}
|
|
11529
11576
|
async launch(planned, req) {
|
|
11530
11577
|
const { target, args } = planned;
|
|
11531
|
-
const
|
|
11578
|
+
const cwd = await physicalPathAsync(this.base, req.cwd);
|
|
11579
|
+
const seen = { ...req.env, HOSTNAME: this.hostname, cwd };
|
|
11532
11580
|
const env = { ...expandDefaults(target.env, seen), ...req.env };
|
|
11533
11581
|
for (const key of target.unset ?? []) delete env[key];
|
|
11534
11582
|
env.HOSTNAME = this.hostname;
|
|
@@ -11539,7 +11587,7 @@ var Launcher = class {
|
|
|
11539
11587
|
await req.fds.closeAll();
|
|
11540
11588
|
throw err;
|
|
11541
11589
|
}
|
|
11542
|
-
return this.start({ ...req, program, argv0: target.argv0, args, env });
|
|
11590
|
+
return this.start({ ...req, cwd, program, argv0: target.argv0, args, env });
|
|
11543
11591
|
}
|
|
11544
11592
|
groupSession(pgid) {
|
|
11545
11593
|
return this.jobs.sessionOf(pgid);
|
|
@@ -11946,7 +11994,8 @@ var Launcher = class {
|
|
|
11946
11994
|
async starting(argv, dir) {
|
|
11947
11995
|
this.catalog = void 0;
|
|
11948
11996
|
this.binfmts = void 0;
|
|
11949
|
-
const
|
|
11997
|
+
const start2 = dir ?? "/";
|
|
11998
|
+
const cwd = await physicalPathAsync(this.base, start2.startsWith("/") ? start2 : `/${start2}`);
|
|
11950
11999
|
const [file = ""] = argv;
|
|
11951
12000
|
await this.base.mkdir(cwd, { recursive: true });
|
|
11952
12001
|
return { cwd, file, planned: await this.plan(file, argv, cwd) };
|