@ai-ecoverse/slicc-kernel 1.67.1 → 1.69.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 +11 -0
- package/dist/index.js +49 -2
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +286 -22
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +606 -82
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +242 -15
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +603 -79
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/process-worker.js
CHANGED
|
@@ -1310,7 +1310,7 @@ function createStreamOps(h) {
|
|
|
1310
1310
|
}
|
|
1311
1311
|
}
|
|
1312
1312
|
};
|
|
1313
|
-
const
|
|
1313
|
+
const opened2 = (node, on, want = 0) => {
|
|
1314
1314
|
const s = node.live;
|
|
1315
1315
|
try {
|
|
1316
1316
|
const handle = bridgeOf(node).hold?.(liveNodePath(node), on, true, s.handle, want);
|
|
@@ -1361,7 +1361,7 @@ function createStreamOps(h) {
|
|
|
1361
1361
|
const want = permitted(stream, created);
|
|
1362
1362
|
live.openCount++;
|
|
1363
1363
|
counted = true;
|
|
1364
|
-
if (live.openCount === 1)
|
|
1364
|
+
if (live.openCount === 1) opened2(stream.node, true, want);
|
|
1365
1365
|
} catch (err) {
|
|
1366
1366
|
if (counted) live.openCount--;
|
|
1367
1367
|
if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
|
|
@@ -1392,7 +1392,7 @@ function createStreamOps(h) {
|
|
|
1392
1392
|
s.len = 0;
|
|
1393
1393
|
s.loaded = false;
|
|
1394
1394
|
held(stream, -1);
|
|
1395
|
-
|
|
1395
|
+
opened2(node, false);
|
|
1396
1396
|
}
|
|
1397
1397
|
},
|
|
1398
1398
|
read(stream, buffer, offset, length, position) {
|
|
@@ -1983,10 +1983,28 @@ function ptyStat(path) {
|
|
|
1983
1983
|
ctime: now
|
|
1984
1984
|
};
|
|
1985
1985
|
}
|
|
1986
|
+
function sealedStat() {
|
|
1987
|
+
const now = /* @__PURE__ */ new Date();
|
|
1988
|
+
return {
|
|
1989
|
+
dev: 22,
|
|
1990
|
+
ino: 1,
|
|
1991
|
+
mode: 8630,
|
|
1992
|
+
nlink: 1,
|
|
1993
|
+
uid: 0,
|
|
1994
|
+
gid: 0,
|
|
1995
|
+
rdev: 10 << 8 | 250,
|
|
1996
|
+
size: 0,
|
|
1997
|
+
blksize: 4096,
|
|
1998
|
+
blocks: 0,
|
|
1999
|
+
atime: now,
|
|
2000
|
+
mtime: now,
|
|
2001
|
+
ctime: now
|
|
2002
|
+
};
|
|
2003
|
+
}
|
|
1986
2004
|
function nonblocking(stream) {
|
|
1987
2005
|
return (stream.flags & O_NONBLOCK) !== 0 ? { nonblock: true } : void 0;
|
|
1988
2006
|
}
|
|
1989
|
-
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC2, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
2007
|
+
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, SEALED_PATH, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC2, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
1990
2008
|
var init_kernel_streams = __esm({
|
|
1991
2009
|
"src/process/kernel-streams.ts"() {
|
|
1992
2010
|
"use strict";
|
|
@@ -2003,6 +2021,7 @@ var init_kernel_streams = __esm({
|
|
|
2003
2021
|
PTY_PATH = /^\/dev\/(?:ptmx|pts\/(\d+))$/;
|
|
2004
2022
|
TTY_PATH = /^\/dev\/tty\d+$/;
|
|
2005
2023
|
TTY_NAME = /^tty\d+$/;
|
|
2024
|
+
SEALED_PATH = "/dev/sealed";
|
|
2006
2025
|
O_CREAT = 64;
|
|
2007
2026
|
O_EXCL = 128;
|
|
2008
2027
|
O_NOCTTY = 256;
|
|
@@ -2076,6 +2095,15 @@ var init_kernel_streams = __esm({
|
|
|
2076
2095
|
if (typeof this.Fs.stat !== "function") return;
|
|
2077
2096
|
stream.stream_ops = { ...stream.stream_ops, getattr: () => this.Fs.stat?.(name2) ?? {} };
|
|
2078
2097
|
}
|
|
2098
|
+
listSealed() {
|
|
2099
|
+
const { analyzePath, mkdev, makedev } = this.Fs;
|
|
2100
|
+
if (!this.sys.openSealed || !analyzePath || !mkdev || !makedev) return;
|
|
2101
|
+
if (analyzePath.call(this.Fs, SEALED_PATH).exists) return;
|
|
2102
|
+
try {
|
|
2103
|
+
mkdev.call(this.Fs, SEALED_PATH, makedev.call(this.Fs, 10, 250));
|
|
2104
|
+
} catch {
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2079
2107
|
creatingTerminal = false;
|
|
2080
2108
|
useTerminalNodes() {
|
|
2081
2109
|
const fs = this.Fs;
|
|
@@ -2102,8 +2130,8 @@ var init_kernel_streams = __esm({
|
|
|
2102
2130
|
fs.readdir = (path) => {
|
|
2103
2131
|
const names = readdir.call(fs, path);
|
|
2104
2132
|
if (path.replace(/\/+$/, "") !== "/dev") return names;
|
|
2105
|
-
const
|
|
2106
|
-
return [...names, ...
|
|
2133
|
+
const missing2 = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name2) => TTY_NAME.test(name2) && !names.includes(name2));
|
|
2134
|
+
return [...names, ...missing2];
|
|
2107
2135
|
};
|
|
2108
2136
|
}
|
|
2109
2137
|
ttyNode(name2) {
|
|
@@ -2168,13 +2196,14 @@ var init_kernel_streams = __esm({
|
|
|
2168
2196
|
if (typeof this.Fs.open !== "function") return;
|
|
2169
2197
|
this.usePtyPaths();
|
|
2170
2198
|
this.useTerminalNodes();
|
|
2199
|
+
this.listSealed();
|
|
2171
2200
|
const open = this.Fs.open.bind(this.Fs);
|
|
2172
2201
|
this.Fs.open = (path, flags, mode) => {
|
|
2173
2202
|
const device2 = typeof path === "string" ? this.devicePath(path) : void 0;
|
|
2174
2203
|
if (device2 !== void 0 && TTY_PATH.test(device2) && !this.terminalExists(device2)) {
|
|
2175
2204
|
throw new this.Fs.ErrnoError(wasiErrno("ENOENT"));
|
|
2176
2205
|
}
|
|
2177
|
-
const pty = this.openPty(open, path, flags, mode);
|
|
2206
|
+
const pty = this.openPty(open, path, flags, mode) ?? this.openSealed(open, path, flags, mode);
|
|
2178
2207
|
if (pty) return pty;
|
|
2179
2208
|
this.refuseExclusiveLink(path, flags);
|
|
2180
2209
|
const stream = this.openRacing(open, path, flags, mode);
|
|
@@ -2232,15 +2261,24 @@ var init_kernel_streams = __esm({
|
|
|
2232
2261
|
const kfd = this.call(
|
|
2233
2262
|
() => pts ? openPts(Number(pts[1]), (flags & O_NOCTTY) !== 0) : openPty()
|
|
2234
2263
|
);
|
|
2264
|
+
return this.vessel(open, kfd, { path, flags, mode }, true);
|
|
2265
|
+
}
|
|
2266
|
+
openSealed(open, path, flags, mode) {
|
|
2267
|
+
const { openSealed } = this.sys;
|
|
2268
|
+
if (path !== SEALED_PATH || !openSealed) return void 0;
|
|
2269
|
+
const kfd = this.call(() => openSealed.call(this.sys));
|
|
2270
|
+
return this.vessel(open, kfd, { path, flags, mode }, false);
|
|
2271
|
+
}
|
|
2272
|
+
vessel(open, kfd, at, terminal) {
|
|
2235
2273
|
let stream;
|
|
2236
2274
|
try {
|
|
2237
|
-
stream = open("/dev/null", flags & ~(O_CREAT | O_EXCL | O_TRUNC2), mode);
|
|
2275
|
+
stream = open("/dev/null", at.flags & ~(O_CREAT | O_EXCL | O_TRUNC2), at.mode);
|
|
2238
2276
|
} catch (e) {
|
|
2239
2277
|
this.sys.close(kfd);
|
|
2240
2278
|
throw e;
|
|
2241
2279
|
}
|
|
2242
|
-
this.attach(stream, kfd,
|
|
2243
|
-
this.nameStream(stream, path);
|
|
2280
|
+
this.attach(stream, kfd, terminal);
|
|
2281
|
+
this.nameStream(stream, at.path);
|
|
2244
2282
|
return stream;
|
|
2245
2283
|
}
|
|
2246
2284
|
usePtyPaths() {
|
|
@@ -2254,6 +2292,7 @@ var init_kernel_streams = __esm({
|
|
|
2254
2292
|
const original = fs[name2];
|
|
2255
2293
|
if (typeof original !== "function") continue;
|
|
2256
2294
|
fs[name2] = (path, ...rest2) => {
|
|
2295
|
+
if (path === SEALED_PATH && this.sys.openSealed) return sealedStat();
|
|
2257
2296
|
const owned = this.ownedTty(path);
|
|
2258
2297
|
if (owned && isPtyPath(path)) return this.owned(path, ptyStat(path));
|
|
2259
2298
|
if (!isPtyPath(path)) {
|
|
@@ -2870,13 +2909,13 @@ function describeFdDir(Fs) {
|
|
|
2870
2909
|
return;
|
|
2871
2910
|
}
|
|
2872
2911
|
const ops = dir?.node_ops;
|
|
2873
|
-
const
|
|
2874
|
-
if (!dir || !
|
|
2912
|
+
const lookup2 = ops?.lookup;
|
|
2913
|
+
if (!dir || !lookup2 || ops.getattr) return;
|
|
2875
2914
|
dir.node_ops = {
|
|
2876
2915
|
...ops,
|
|
2877
2916
|
getattr: () => syntheticAttr(DIR_MODE, 1),
|
|
2878
2917
|
lookup: (parent, name2) => {
|
|
2879
|
-
const entry =
|
|
2918
|
+
const entry = lookup2(parent, name2);
|
|
2880
2919
|
entry.node_ops = {
|
|
2881
2920
|
...entry.node_ops,
|
|
2882
2921
|
getattr: () => syntheticAttr(LINK_MODE, entry.id ?? 0)
|
|
@@ -4166,7 +4205,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
|
|
|
4166
4205
|
return found;
|
|
4167
4206
|
};
|
|
4168
4207
|
const procOps = proc.node_ops;
|
|
4169
|
-
const
|
|
4208
|
+
const lookup2 = procOps.lookup?.bind(procOps);
|
|
4170
4209
|
const readdir = procOps.readdir?.bind(procOps);
|
|
4171
4210
|
const listAll = (node) => {
|
|
4172
4211
|
const names = new Set(readdir ? readdir(node) : [".", ".."]);
|
|
@@ -4189,8 +4228,8 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
|
|
|
4189
4228
|
() => systemFile(name2, procList(), Date.now(), memory)
|
|
4190
4229
|
);
|
|
4191
4230
|
}
|
|
4192
|
-
if (!
|
|
4193
|
-
return
|
|
4231
|
+
if (!lookup2) throw error();
|
|
4232
|
+
return lookup2(parent, name2);
|
|
4194
4233
|
},
|
|
4195
4234
|
readdir: (node) => listAll(node)
|
|
4196
4235
|
};
|
|
@@ -4403,6 +4442,9 @@ function kernelSys(transport) {
|
|
|
4403
4442
|
openPts(n, noctty) {
|
|
4404
4443
|
return json2(call2({ op: "pty-slave-open", n, noctty }, `pty-slave-open ${n}`));
|
|
4405
4444
|
},
|
|
4445
|
+
openSealed() {
|
|
4446
|
+
return json2(call2({ op: "fd-open-sealed" }, "fd-open-sealed"));
|
|
4447
|
+
},
|
|
4406
4448
|
ptyNumbers() {
|
|
4407
4449
|
return json2(call2({ op: "pty-list" }, "pty-list"));
|
|
4408
4450
|
},
|
|
@@ -5405,6 +5447,34 @@ var init_wasi_files = __esm({
|
|
|
5405
5447
|
}
|
|
5406
5448
|
});
|
|
5407
5449
|
|
|
5450
|
+
// src/kernel/pipe.ts
|
|
5451
|
+
var PIPE_CAPACITY;
|
|
5452
|
+
var init_pipe = __esm({
|
|
5453
|
+
"src/kernel/pipe.ts"() {
|
|
5454
|
+
"use strict";
|
|
5455
|
+
PIPE_CAPACITY = 64 * 1024;
|
|
5456
|
+
}
|
|
5457
|
+
});
|
|
5458
|
+
|
|
5459
|
+
// src/kernel/fd-table.ts
|
|
5460
|
+
function deviceAt(path) {
|
|
5461
|
+
return DEVICE_PATHS.get(path);
|
|
5462
|
+
}
|
|
5463
|
+
var DEVICE_PATHS;
|
|
5464
|
+
var init_fd_table = __esm({
|
|
5465
|
+
"src/kernel/fd-table.ts"() {
|
|
5466
|
+
"use strict";
|
|
5467
|
+
init_pipe();
|
|
5468
|
+
DEVICE_PATHS = /* @__PURE__ */ new Map([
|
|
5469
|
+
["/dev/null", "null"],
|
|
5470
|
+
["/dev/zero", "zero"],
|
|
5471
|
+
["/dev/full", "full"],
|
|
5472
|
+
["/dev/urandom", "urandom"],
|
|
5473
|
+
["/dev/random", "urandom"]
|
|
5474
|
+
]);
|
|
5475
|
+
}
|
|
5476
|
+
});
|
|
5477
|
+
|
|
5408
5478
|
// src/process/wasi/wasi-fds.ts
|
|
5409
5479
|
function stdioAlias(path) {
|
|
5410
5480
|
const m = /^\/dev\/(?:(stdin)|(stdout)|(stderr)|fd\/(\d+))$/.exec(path);
|
|
@@ -5412,7 +5482,7 @@ function stdioAlias(path) {
|
|
|
5412
5482
|
return m[1] ? 0 : m[2] ? 1 : m[3] ? 2 : Number(m[4]);
|
|
5413
5483
|
}
|
|
5414
5484
|
function deviceOf(path) {
|
|
5415
|
-
return
|
|
5485
|
+
return deviceAt(path);
|
|
5416
5486
|
}
|
|
5417
5487
|
function within(path, root) {
|
|
5418
5488
|
return path === root || path.startsWith(root === "/" ? "/" : `${root}/`);
|
|
@@ -5480,10 +5550,11 @@ function promoteRequest(fd, f, handed) {
|
|
|
5480
5550
|
...f.buffer.handle !== void 0 ? { handle: f.buffer.handle } : {}
|
|
5481
5551
|
};
|
|
5482
5552
|
}
|
|
5483
|
-
var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND,
|
|
5553
|
+
var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND, SEALED_PATH2, WasiFds, GEN;
|
|
5484
5554
|
var init_wasi_fds = __esm({
|
|
5485
5555
|
"src/process/wasi/wasi-fds.ts"() {
|
|
5486
5556
|
"use strict";
|
|
5557
|
+
init_fd_table();
|
|
5487
5558
|
init_sync_fs_wire();
|
|
5488
5559
|
init_wasi_abi();
|
|
5489
5560
|
init_wasi_files();
|
|
@@ -5492,13 +5563,7 @@ var init_wasi_fds = __esm({
|
|
|
5492
5563
|
O_WRONLY4 = 1;
|
|
5493
5564
|
O_RDWR4 = 2;
|
|
5494
5565
|
O_APPEND = 1024;
|
|
5495
|
-
|
|
5496
|
-
"/dev/null": "null",
|
|
5497
|
-
"/dev/zero": "zero",
|
|
5498
|
-
"/dev/full": "full",
|
|
5499
|
-
"/dev/urandom": "urandom",
|
|
5500
|
-
"/dev/random": "urandom"
|
|
5501
|
-
};
|
|
5566
|
+
SEALED_PATH2 = "/dev/sealed";
|
|
5502
5567
|
WasiFds = class {
|
|
5503
5568
|
table = /* @__PURE__ */ new Map();
|
|
5504
5569
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -5963,16 +6028,30 @@ var init_wasi_fds = __esm({
|
|
|
5963
6028
|
const joined2 = path.startsWith("/") ? path : `${this.dir(dirfd).path}/${path}`;
|
|
5964
6029
|
return joined2.split("/").includes("..") ? physical(this.fs, joined2) : normalize(joined2);
|
|
5965
6030
|
}
|
|
6031
|
+
openKernelDevice(path, oflags, fdflags) {
|
|
6032
|
+
const { openSealed, openTty } = this.kernel.sys;
|
|
6033
|
+
const nonblock = (fdflags & FDFLAGS.NONBLOCK) !== 0;
|
|
6034
|
+
let fd;
|
|
6035
|
+
let kind;
|
|
6036
|
+
if (path === SEALED_PATH2 && openSealed) {
|
|
6037
|
+
if (oflags & OFLAGS.DIRECTORY) throw new WasiError("ENOTDIR");
|
|
6038
|
+
if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
|
|
6039
|
+
fd = openSealed.call(this.kernel.sys);
|
|
6040
|
+
kind = "sealed";
|
|
6041
|
+
} else if (path === "/dev/tty" || /^\/dev\/tty\d+$/.test(path)) {
|
|
6042
|
+
fd = openTty?.call(this.kernel.sys, path === "/dev/tty" ? void 0 : path);
|
|
6043
|
+
if (fd === void 0) throw new WasiError("ENXIO");
|
|
6044
|
+
kind = "tty";
|
|
6045
|
+
} else return void 0;
|
|
6046
|
+
this.adopt(fd, kind, nonblock);
|
|
6047
|
+
this.bump();
|
|
6048
|
+
return fd;
|
|
6049
|
+
}
|
|
5966
6050
|
open(path, oflags, rights, fdflags) {
|
|
5967
6051
|
const device2 = deviceOf(path);
|
|
5968
6052
|
if (device2) return this.install({ type: "device", device: device2 });
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
if (fd === void 0) throw new WasiError("ENXIO");
|
|
5972
|
-
this.table.set(fd, { ...kernelEntry2(), kind: "tty" });
|
|
5973
|
-
this.bump();
|
|
5974
|
-
return fd;
|
|
5975
|
-
}
|
|
6053
|
+
const kernelDevice = this.openKernelDevice(path, oflags, fdflags);
|
|
6054
|
+
if (kernelDevice !== void 0) return kernelDevice;
|
|
5976
6055
|
const alias = stdioAlias(path);
|
|
5977
6056
|
if (alias !== void 0) return this.reopen(alias);
|
|
5978
6057
|
const exclusive = (oflags & OFLAGS.CREAT) !== 0 && (oflags & OFLAGS.EXCL) !== 0;
|
|
@@ -6413,6 +6492,7 @@ function filestatOf(path, s) {
|
|
|
6413
6492
|
function kernelFiletype(kind) {
|
|
6414
6493
|
switch (kind) {
|
|
6415
6494
|
case "tty":
|
|
6495
|
+
case "sealed":
|
|
6416
6496
|
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
|
|
6417
6497
|
case "device":
|
|
6418
6498
|
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
|
|
@@ -6453,7 +6533,7 @@ function wrap(table) {
|
|
|
6453
6533
|
}
|
|
6454
6534
|
return out;
|
|
6455
6535
|
}
|
|
6456
|
-
var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, AT_EACCESS2, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
|
|
6536
|
+
var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, AT_EACCESS2, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SEALED_MODE, WasiHost;
|
|
6457
6537
|
var init_wasi_host = __esm({
|
|
6458
6538
|
"src/process/wasi/wasi-host.ts"() {
|
|
6459
6539
|
"use strict";
|
|
@@ -6483,6 +6563,7 @@ var init_wasi_host = __esm({
|
|
|
6483
6563
|
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
|
|
6484
6564
|
MAX_READ = 1024 * 1024;
|
|
6485
6565
|
SIGPIPE_EXIT = 141;
|
|
6566
|
+
SEALED_MODE = 8630;
|
|
6486
6567
|
WasiHost = class {
|
|
6487
6568
|
mem = new WasiMemory();
|
|
6488
6569
|
fds;
|
|
@@ -6568,7 +6649,9 @@ var init_wasi_host = __esm({
|
|
|
6568
6649
|
const fdOwned = (fd) => {
|
|
6569
6650
|
const e = fds.get(fd);
|
|
6570
6651
|
if (e.type === "device") return ROOT_IDS;
|
|
6571
|
-
|
|
6652
|
+
const kind = e.type === "kernel" ? fds.kind(fd, e) : "file";
|
|
6653
|
+
if (kind === "sealed") return ROOT_IDS;
|
|
6654
|
+
if (kind !== "file") return void 0;
|
|
6572
6655
|
try {
|
|
6573
6656
|
return this.o.fs.stat(pathOf(fd));
|
|
6574
6657
|
} catch (err) {
|
|
@@ -6577,7 +6660,7 @@ var init_wasi_host = __esm({
|
|
|
6577
6660
|
}
|
|
6578
6661
|
};
|
|
6579
6662
|
const pathOwned = (path, follow2) => {
|
|
6580
|
-
if (
|
|
6663
|
+
if (this.synthetic(path)) return ROOT_IDS;
|
|
6581
6664
|
return follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
|
|
6582
6665
|
};
|
|
6583
6666
|
return wrap({
|
|
@@ -6592,11 +6675,11 @@ var init_wasi_host = __esm({
|
|
|
6592
6675
|
this.writeFilestat(statOut, this.fdFilestat(fd));
|
|
6593
6676
|
owner(fdOwned(fd), out);
|
|
6594
6677
|
},
|
|
6595
|
-
path_filestat_owner: (dirfd,
|
|
6678
|
+
path_filestat_owner: (dirfd, lookup2, p, l, statOut, out) => {
|
|
6596
6679
|
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
6597
6680
|
const path = at(dirfd, p, l);
|
|
6598
|
-
this.writeFilestat(statOut, this.pathFilestat(path,
|
|
6599
|
-
owner(pathOwned(path, (
|
|
6681
|
+
this.writeFilestat(statOut, this.pathFilestat(path, lookup2));
|
|
6682
|
+
owner(pathOwned(path, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
|
|
6600
6683
|
},
|
|
6601
6684
|
path_owner: (dirfd, p, l, flags, out) => {
|
|
6602
6685
|
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
@@ -6606,7 +6689,7 @@ var init_wasi_host = __esm({
|
|
|
6606
6689
|
path_access: (dirfd, p, l, amode, flags) => {
|
|
6607
6690
|
const path = at(dirfd, p, l);
|
|
6608
6691
|
const nofollow = (flags & AT_SYMLINK_NOFOLLOW2) !== 0;
|
|
6609
|
-
if (
|
|
6692
|
+
if (this.synthetic(path)) {
|
|
6610
6693
|
if (this.o.fs.owners && amode & 1) throw new WasiError("EACCES");
|
|
6611
6694
|
return;
|
|
6612
6695
|
}
|
|
@@ -6623,12 +6706,14 @@ var init_wasi_host = __esm({
|
|
|
6623
6706
|
},
|
|
6624
6707
|
fd_mode: (fd, out) => {
|
|
6625
6708
|
const e = fds.get(fd);
|
|
6626
|
-
const
|
|
6627
|
-
const mode =
|
|
6709
|
+
const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
|
|
6710
|
+
const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
|
|
6628
6711
|
mem.view().setUint32(out, mode, true);
|
|
6629
6712
|
},
|
|
6630
6713
|
path_mode: (dirfd, p, l, flags, out) => {
|
|
6631
6714
|
const path = at(dirfd, p, l);
|
|
6715
|
+
if (path === SEALED_PATH2 && this.o.kernel.sys.openSealed)
|
|
6716
|
+
return void mem.view().setUint32(out, SEALED_MODE, true);
|
|
6632
6717
|
const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
|
|
6633
6718
|
mem.view().setUint32(out, modeOf(st), true);
|
|
6634
6719
|
}
|
|
@@ -6816,15 +6901,15 @@ var init_wasi_host = __esm({
|
|
|
6816
6901
|
path_open: (dirfd, _lookup, p, l, oflags, rights, _inheriting, fdflags, out) => {
|
|
6817
6902
|
const path = at(dirfd, p, l);
|
|
6818
6903
|
if (deviceOf(path)) this.interrupted?.();
|
|
6819
|
-
const fresh = (oflags & OFLAGS.CREAT) !== 0 && !o.fs.exists(path);
|
|
6904
|
+
const fresh = (oflags & OFLAGS.CREAT) !== 0 && !this.synthetic(path) && !o.fs.exists(path);
|
|
6820
6905
|
mem.view().setUint32(out, fds.open(path, oflags, rights, fdflags), true);
|
|
6821
6906
|
if (fresh) this.created(path, 438);
|
|
6822
6907
|
},
|
|
6823
|
-
path_filestat_get: (dirfd,
|
|
6824
|
-
path_filestat_set_times: (dirfd,
|
|
6908
|
+
path_filestat_get: (dirfd, lookup2, p, l, out) => void this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup2)),
|
|
6909
|
+
path_filestat_set_times: (dirfd, lookup2, p, l, atim, mtim, flags) => {
|
|
6825
6910
|
const path = at(dirfd, p, l);
|
|
6826
6911
|
fds.flushPath(path);
|
|
6827
|
-
this.setTimes(path, atim, mtim, flags, (
|
|
6912
|
+
this.setTimes(path, atim, mtim, flags, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0);
|
|
6828
6913
|
},
|
|
6829
6914
|
path_create_directory: (dirfd, p, l) => {
|
|
6830
6915
|
const path = at(dirfd, p, l);
|
|
@@ -6857,10 +6942,10 @@ var init_wasi_host = __esm({
|
|
|
6857
6942
|
mem.bytes(buf, n).set(target.subarray(0, n));
|
|
6858
6943
|
mem.view().setUint32(used, n, true);
|
|
6859
6944
|
},
|
|
6860
|
-
path_link: (fd,
|
|
6945
|
+
path_link: (fd, lookup2, p, l, fd2, p2, l2) => {
|
|
6861
6946
|
const from = at(fd, p, l);
|
|
6862
6947
|
const to = at(fd2, p2, l2);
|
|
6863
|
-
const follow2 = (
|
|
6948
|
+
const follow2 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
6864
6949
|
const source = follow2 ? physicalPath(o.fs, from) : from;
|
|
6865
6950
|
fds.flushPath(from);
|
|
6866
6951
|
if (source !== from) fds.flushPath(source);
|
|
@@ -7125,8 +7210,11 @@ var init_wasi_host = __esm({
|
|
|
7125
7210
|
const out = this.sized(path, s, size);
|
|
7126
7211
|
return gone ? { ...out, nlink: 0n } : out;
|
|
7127
7212
|
}
|
|
7128
|
-
|
|
7129
|
-
|
|
7213
|
+
synthetic(path) {
|
|
7214
|
+
return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed;
|
|
7215
|
+
}
|
|
7216
|
+
pathFilestat(path, lookup2) {
|
|
7217
|
+
if (this.synthetic(path)) {
|
|
7130
7218
|
return this.local({
|
|
7131
7219
|
filetype: FILETYPE.CHARACTER_DEVICE,
|
|
7132
7220
|
size: 0n,
|
|
@@ -7135,7 +7223,7 @@ var init_wasi_host = __esm({
|
|
|
7135
7223
|
});
|
|
7136
7224
|
}
|
|
7137
7225
|
this.fds.flushPath(path);
|
|
7138
|
-
const follow2 = (
|
|
7226
|
+
const follow2 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
7139
7227
|
return filestatOf(path, follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path));
|
|
7140
7228
|
}
|
|
7141
7229
|
setTimes(path, atim, mtim, flags, follow2 = true) {
|
|
@@ -7333,12 +7421,12 @@ var init_wasix_process = __esm({
|
|
|
7333
7421
|
fds.promoteFiles();
|
|
7334
7422
|
const map = fds.inheritable();
|
|
7335
7423
|
const nulls = /* @__PURE__ */ new Set();
|
|
7336
|
-
const
|
|
7424
|
+
const opened2 = [];
|
|
7337
7425
|
let cwd = this.host.cwd;
|
|
7338
7426
|
try {
|
|
7339
|
-
for (const op of ops) cwd = this.applyFdOp(op, { map, nulls, opened }, cwd);
|
|
7427
|
+
for (const op of ops) cwd = this.applyFdOp(op, { map, nulls, opened: opened2 }, cwd);
|
|
7340
7428
|
} catch (e) {
|
|
7341
|
-
for (const kfd of
|
|
7429
|
+
for (const kfd of opened2) this.host.o.kernel.sys.close(kfd);
|
|
7342
7430
|
throw e;
|
|
7343
7431
|
}
|
|
7344
7432
|
const stdio = [0, 1, 2].map((fd) => {
|
|
@@ -7349,10 +7437,10 @@ var init_wasix_process = __esm({
|
|
|
7349
7437
|
...[...map].filter(([fd]) => fd > 2).map(([fd, kernel]) => ({ fd, kernel })),
|
|
7350
7438
|
...[...nulls].filter((fd) => fd > 2).map((fd) => ({ fd, device: "null" }))
|
|
7351
7439
|
];
|
|
7352
|
-
return { stdio, inherit, cwd, opened };
|
|
7440
|
+
return { stdio, inherit, cwd, opened: opened2 };
|
|
7353
7441
|
}
|
|
7354
7442
|
applyFdOp(op, slots3, cwd) {
|
|
7355
|
-
const { map, nulls, opened } = slots3;
|
|
7443
|
+
const { map, nulls, opened: opened2 } = slots3;
|
|
7356
7444
|
const { fds } = this.host;
|
|
7357
7445
|
const point = (fd, kfd) => {
|
|
7358
7446
|
if (kfd === void 0) {
|
|
@@ -7375,7 +7463,7 @@ var init_wasix_process = __esm({
|
|
|
7375
7463
|
point(op.fd, void 0);
|
|
7376
7464
|
} else if (op.cmd === "open") {
|
|
7377
7465
|
const kfd = this.openFor(op, cwd);
|
|
7378
|
-
|
|
7466
|
+
opened2.push(kfd);
|
|
7379
7467
|
point(op.fd, kfd);
|
|
7380
7468
|
} else if (op.cmd === "chdir") return this.physicalFrom(cwd, op.path);
|
|
7381
7469
|
else return physicalPath(this.host.o.fs, fds.dir(op.fd).path);
|
|
@@ -7397,7 +7485,7 @@ var init_wasix_process = __esm({
|
|
|
7397
7485
|
});
|
|
7398
7486
|
}
|
|
7399
7487
|
spawn(req, exec = false) {
|
|
7400
|
-
const { stdio, inherit, cwd, opened } = this.childFds(req.ops ?? []);
|
|
7488
|
+
const { stdio, inherit, cwd, opened: opened2 } = this.childFds(req.ops ?? []);
|
|
7401
7489
|
try {
|
|
7402
7490
|
const spawn = {
|
|
7403
7491
|
op: "proc-spawn",
|
|
@@ -7412,7 +7500,7 @@ var init_wasix_process = __esm({
|
|
|
7412
7500
|
};
|
|
7413
7501
|
return restarted2(() => this.call(spawn));
|
|
7414
7502
|
} finally {
|
|
7415
|
-
for (const kfd of
|
|
7503
|
+
for (const kfd of opened2) this.host.o.kernel.sys.close(kfd);
|
|
7416
7504
|
this.host.o.fs.invalidate?.();
|
|
7417
7505
|
}
|
|
7418
7506
|
}
|
|
@@ -9757,8 +9845,8 @@ var init_wasix_host = __esm({
|
|
|
9757
9845
|
mem.view().setUint16(out, host.fds.cloexec.has(fd) ? FDFLAGSEXT_CLOEXEC : 0, true);
|
|
9758
9846
|
},
|
|
9759
9847
|
fd_fdflags_set: (fd, flags) => void host.fds.setCloexec(fd, (flags & FDFLAGSEXT_CLOEXEC) !== 0),
|
|
9760
|
-
path_open2: (dirfd,
|
|
9761
|
-
const r = preview1.path_open(dirfd,
|
|
9848
|
+
path_open2: (dirfd, lookup2, p, l, oflags, rights, inheriting, fdflags, fdflagsext, out) => {
|
|
9849
|
+
const r = preview1.path_open(dirfd, lookup2, p, l, oflags, rights, inheriting, fdflags, out);
|
|
9762
9850
|
if (r === E.SUCCESS && fdflagsext & FDFLAGSEXT_CLOEXEC)
|
|
9763
9851
|
host.fds.setCloexec(mem.view().getUint32(out, true), true);
|
|
9764
9852
|
return r;
|
|
@@ -10731,6 +10819,11 @@ function untilAborted(work, signal) {
|
|
|
10731
10819
|
work.then(done, done);
|
|
10732
10820
|
});
|
|
10733
10821
|
}
|
|
10822
|
+
function caughtOf(handlers) {
|
|
10823
|
+
let caught = 0;
|
|
10824
|
+
for (const sig of handlers.keys()) caught |= sigbit(sig);
|
|
10825
|
+
return caught;
|
|
10826
|
+
}
|
|
10734
10827
|
var JsCallError, JsKernel;
|
|
10735
10828
|
var init_js_kernel = __esm({
|
|
10736
10829
|
"src/process/js/js-kernel.ts"() {
|
|
@@ -10758,6 +10851,7 @@ var init_js_kernel = __esm({
|
|
|
10758
10851
|
reported = { caught: 0, ignored: 0 };
|
|
10759
10852
|
watching = false;
|
|
10760
10853
|
faulted = false;
|
|
10854
|
+
syncLane;
|
|
10761
10855
|
constructor(o) {
|
|
10762
10856
|
this.header = new Int32Array(o.sab, 0, SAB_HEADER_I32);
|
|
10763
10857
|
this.transport = o.transport;
|
|
@@ -10860,16 +10954,41 @@ var init_js_kernel = __esm({
|
|
|
10860
10954
|
if (sig === SIG.KILL || sig === SIG.STOP) {
|
|
10861
10955
|
return Promise.reject(new JsCallError("EINVAL", "signal"));
|
|
10862
10956
|
}
|
|
10957
|
+
if (this.syncLane) {
|
|
10958
|
+
try {
|
|
10959
|
+
this.changeNow(this.syncLane, sig, handler);
|
|
10960
|
+
return Promise.resolve();
|
|
10961
|
+
} catch (err) {
|
|
10962
|
+
return Promise.reject(err);
|
|
10963
|
+
}
|
|
10964
|
+
}
|
|
10863
10965
|
const run = this.changing.then(() => this.change(sig, handler));
|
|
10864
10966
|
this.changing = run.catch(() => void 0);
|
|
10865
10967
|
return run;
|
|
10866
10968
|
}
|
|
10867
|
-
|
|
10969
|
+
changeNow(lane, sig, handler) {
|
|
10970
|
+
const { handlers, ignored } = this.disposed(sig, handler);
|
|
10971
|
+
const defaults = handler === "default" ? sigbit(sig) : 0;
|
|
10972
|
+
const caught = caughtOf(handlers);
|
|
10973
|
+
if (caught !== this.reported.caught || ignored !== this.reported.ignored || defaults !== 0) {
|
|
10974
|
+
const r = lane({ op: "sig-mask", caught, ignored, ...defaults ? { defaults } : {} });
|
|
10975
|
+
if (!r.ok) throw new JsCallError(r.errno, "sig-mask");
|
|
10976
|
+
this.reported = { caught, ignored };
|
|
10977
|
+
}
|
|
10978
|
+
this.handlers = handlers;
|
|
10979
|
+
this.ignored = ignored;
|
|
10980
|
+
if (handlers.size > 0) void this.watch();
|
|
10981
|
+
}
|
|
10982
|
+
disposed(sig, handler) {
|
|
10868
10983
|
const handlers = new Map(this.handlers);
|
|
10869
10984
|
handlers.delete(sig);
|
|
10870
10985
|
let ignored = this.ignored & ~sigbit(sig);
|
|
10871
10986
|
if (handler === "ignore") ignored |= sigbit(sig);
|
|
10872
10987
|
else if (handler !== "default") handlers.set(sig, handler);
|
|
10988
|
+
return { handlers, ignored };
|
|
10989
|
+
}
|
|
10990
|
+
async change(sig, handler) {
|
|
10991
|
+
const { handlers, ignored } = this.disposed(sig, handler);
|
|
10873
10992
|
await this.report(handlers, ignored, handler === "default" ? sigbit(sig) : 0);
|
|
10874
10993
|
this.handlers = handlers;
|
|
10875
10994
|
this.ignored = ignored;
|
|
@@ -10879,8 +10998,7 @@ var init_js_kernel = __esm({
|
|
|
10879
10998
|
this.call({ op: "proc-kill", pid: this.pid, sig }).catch(this.onError);
|
|
10880
10999
|
}
|
|
10881
11000
|
async report(handlers, ignored, defaults) {
|
|
10882
|
-
|
|
10883
|
-
for (const sig of handlers.keys()) caught |= sigbit(sig);
|
|
11001
|
+
const caught = caughtOf(handlers);
|
|
10884
11002
|
const same = caught === this.reported.caught && ignored === this.reported.ignored;
|
|
10885
11003
|
if (same && defaults === 0) return;
|
|
10886
11004
|
this.reported = { caught, ignored };
|
|
@@ -11100,6 +11218,344 @@ var init_js_io = __esm({
|
|
|
11100
11218
|
}
|
|
11101
11219
|
});
|
|
11102
11220
|
|
|
11221
|
+
// src/process/js/js-dev.ts
|
|
11222
|
+
function inDev(abs) {
|
|
11223
|
+
return abs.startsWith("/dev") && (abs.length === 4 || abs[4] === "/");
|
|
11224
|
+
}
|
|
11225
|
+
function missing(path) {
|
|
11226
|
+
throw new JsCallError("ENOENT", path);
|
|
11227
|
+
}
|
|
11228
|
+
function nodeStat(mode, size = 0, owner) {
|
|
11229
|
+
return {
|
|
11230
|
+
isFile: false,
|
|
11231
|
+
isDirectory: (mode & S_IFMT2) === DIR,
|
|
11232
|
+
isSymbolicLink: (mode & S_IFMT2) === LINK,
|
|
11233
|
+
size,
|
|
11234
|
+
mode,
|
|
11235
|
+
mtimeMs: BORN,
|
|
11236
|
+
atimeMs: BORN,
|
|
11237
|
+
ctimeMs: BORN,
|
|
11238
|
+
nlink: 1,
|
|
11239
|
+
uid: owner?.uid ?? 0,
|
|
11240
|
+
gid: owner?.gid ?? 0
|
|
11241
|
+
};
|
|
11242
|
+
}
|
|
11243
|
+
function* lookup(abs) {
|
|
11244
|
+
if (abs === "/dev") return { kind: "dir", mode: DIR | 493 };
|
|
11245
|
+
const name2 = abs.slice("/dev/".length);
|
|
11246
|
+
if (DEVICES2.includes(name2)) return { kind: "device" };
|
|
11247
|
+
if (name2 === "tty") return { kind: "tty" };
|
|
11248
|
+
const std = STDIO3.indexOf(name2);
|
|
11249
|
+
if (std >= 0) return { kind: "link", target: `${SELF_FD}/${std}`, fd: std };
|
|
11250
|
+
if (name2 === "fd") return { kind: "link", target: SELF_FD };
|
|
11251
|
+
const fd = /^fd\/(\d+)$/.exec(name2)?.[1];
|
|
11252
|
+
if (fd !== void 0) return { kind: "fd", fd: Number(fd) };
|
|
11253
|
+
if (/^tty\d+$/.test(name2)) {
|
|
11254
|
+
const names = yield { op: "fd-tty-names" };
|
|
11255
|
+
if (names.includes(abs)) return { kind: "terminal", name: abs };
|
|
11256
|
+
}
|
|
11257
|
+
const pts = /^pts\/(\d+)$/.exec(name2)?.[1];
|
|
11258
|
+
if (pts !== void 0) {
|
|
11259
|
+
const open = yield { op: "pty-list" };
|
|
11260
|
+
if (open.includes(Number(pts))) return { kind: "terminal", name: abs, pts: Number(pts) };
|
|
11261
|
+
}
|
|
11262
|
+
return missing(abs);
|
|
11263
|
+
}
|
|
11264
|
+
function* fdInfo(fd, path) {
|
|
11265
|
+
try {
|
|
11266
|
+
return yield { op: "fd-info", fd };
|
|
11267
|
+
} catch (err) {
|
|
11268
|
+
if (err instanceof JsCallError && err.code === "EBADF") return missing(path);
|
|
11269
|
+
throw err;
|
|
11270
|
+
}
|
|
11271
|
+
}
|
|
11272
|
+
function* pathStat(path) {
|
|
11273
|
+
const s = parseSyncFsStat(yield { op: "stat", path });
|
|
11274
|
+
if (!s) throw new JsCallError("EIO", "stat");
|
|
11275
|
+
return s;
|
|
11276
|
+
}
|
|
11277
|
+
function* terminalStat(name2) {
|
|
11278
|
+
const owner = yield { op: "fd-tty-owner", name: name2 };
|
|
11279
|
+
if (owner) return nodeStat(CHAR | (owner.mode ?? 400), 0, owner);
|
|
11280
|
+
return nodeStat(CHAR | (name2.startsWith("/dev/pts/") ? 400 : 438));
|
|
11281
|
+
}
|
|
11282
|
+
function* fdStat(fd, path) {
|
|
11283
|
+
const info = yield* fdInfo(fd, path);
|
|
11284
|
+
if (info.meta && "dir" in info.meta) return yield* pathStat(info.meta.dir);
|
|
11285
|
+
if (info.kind === "file") {
|
|
11286
|
+
const file = yield { op: "fd-vfs-stat", fd };
|
|
11287
|
+
if (file.orphan) return { ...nodeStat(33152, file.size), isFile: true };
|
|
11288
|
+
return yield* pathStat(file.path);
|
|
11289
|
+
}
|
|
11290
|
+
if (info.terminal) return yield* terminalStat(info.terminal);
|
|
11291
|
+
if (info.kind === "device" || info.kind === "tty") return nodeStat(CHAR | 438);
|
|
11292
|
+
if (info.kind === "socket") return nodeStat(49663);
|
|
11293
|
+
return nodeStat(4480);
|
|
11294
|
+
}
|
|
11295
|
+
function* fdTarget(fd, path) {
|
|
11296
|
+
const info = yield* fdInfo(fd, path);
|
|
11297
|
+
if (info.meta && "dir" in info.meta) return info.meta.dir;
|
|
11298
|
+
if (info.kind === "file") return (yield { op: "fd-vfs-stat", fd }).path;
|
|
11299
|
+
if (info.terminal) return info.terminal;
|
|
11300
|
+
if (info.meta && "device" in info.meta) return `/dev/${info.meta.device}`;
|
|
11301
|
+
return `${info.kind === "socket" ? "socket" : "pipe"}:[${fd}]`;
|
|
11302
|
+
}
|
|
11303
|
+
function linkStat(target) {
|
|
11304
|
+
return nodeStat(LINK | 511, target.length);
|
|
11305
|
+
}
|
|
11306
|
+
function* devStat(abs, follow2) {
|
|
11307
|
+
const node = yield* lookup(abs);
|
|
11308
|
+
switch (node.kind) {
|
|
11309
|
+
case "dir":
|
|
11310
|
+
return nodeStat(node.mode);
|
|
11311
|
+
case "device":
|
|
11312
|
+
case "tty":
|
|
11313
|
+
return nodeStat(CHAR | 438);
|
|
11314
|
+
case "terminal":
|
|
11315
|
+
return yield* terminalStat(node.name);
|
|
11316
|
+
case "link":
|
|
11317
|
+
if (!follow2) return linkStat(node.target);
|
|
11318
|
+
return node.fd === void 0 ? nodeStat(DIR | 365) : yield* fdStat(node.fd, abs);
|
|
11319
|
+
case "fd":
|
|
11320
|
+
return follow2 ? yield* fdStat(node.fd, abs) : linkStat(yield* fdTarget(node.fd, abs));
|
|
11321
|
+
}
|
|
11322
|
+
}
|
|
11323
|
+
function* devExists(abs) {
|
|
11324
|
+
try {
|
|
11325
|
+
yield* devStat(abs, true);
|
|
11326
|
+
return true;
|
|
11327
|
+
} catch (err) {
|
|
11328
|
+
if (err instanceof JsCallError) return false;
|
|
11329
|
+
throw err;
|
|
11330
|
+
}
|
|
11331
|
+
}
|
|
11332
|
+
function* devReadlink(abs) {
|
|
11333
|
+
const node = yield* lookup(abs);
|
|
11334
|
+
if (node.kind === "link") return node.target;
|
|
11335
|
+
if (node.kind === "fd") return yield* fdTarget(node.fd, abs);
|
|
11336
|
+
throw new JsCallError("EINVAL", abs);
|
|
11337
|
+
}
|
|
11338
|
+
function* devReaddir(abs) {
|
|
11339
|
+
if (abs === "/dev/fd") {
|
|
11340
|
+
const fds = yield { op: "fd-list" };
|
|
11341
|
+
return fds.map(({ fd }) => String(fd));
|
|
11342
|
+
}
|
|
11343
|
+
const node = yield* lookup(abs);
|
|
11344
|
+
if (node.kind !== "dir") throw new JsCallError("ENOTDIR", abs);
|
|
11345
|
+
const names = yield { op: "fd-tty-names" };
|
|
11346
|
+
const ttys = names.filter((n) => /^\/dev\/tty\d+$/.test(n)).map((n) => n.slice(5));
|
|
11347
|
+
return [...DEVICES2, "tty", "fd", ...STDIO3, ...ttys].sort();
|
|
11348
|
+
}
|
|
11349
|
+
function* aliasOf(fd, abs, o) {
|
|
11350
|
+
const info = yield* fdInfo(fd, abs);
|
|
11351
|
+
const file = info.kind === "file";
|
|
11352
|
+
if (file) {
|
|
11353
|
+
const at = yield { op: "fd-vfs-stat", fd };
|
|
11354
|
+
if (!at.orphan)
|
|
11355
|
+
return { fd: yield openRequest(at.path, { ...o, create: false }), file };
|
|
11356
|
+
}
|
|
11357
|
+
const copy2 = yield { op: "fd-dup", fd, min: 3 };
|
|
11358
|
+
if (file && o.truncate) {
|
|
11359
|
+
try {
|
|
11360
|
+
yield { op: "fd-resize", fd: copy2, size: 0 };
|
|
11361
|
+
} catch (err) {
|
|
11362
|
+
yield { op: "fd-close", fd: copy2 };
|
|
11363
|
+
throw err;
|
|
11364
|
+
}
|
|
11365
|
+
}
|
|
11366
|
+
return { fd: copy2, file };
|
|
11367
|
+
}
|
|
11368
|
+
function* opened(abs, o) {
|
|
11369
|
+
const node = yield* lookup(abs);
|
|
11370
|
+
if (isExclusive(o)) throw new JsCallError("EEXIST", abs);
|
|
11371
|
+
switch (node.kind) {
|
|
11372
|
+
case "device":
|
|
11373
|
+
return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
|
|
11374
|
+
case "tty":
|
|
11375
|
+
return { fd: yield { op: "fd-open-tty" }, file: false };
|
|
11376
|
+
case "terminal": {
|
|
11377
|
+
const req = node.pts === void 0 ? { op: "fd-open-tty", name: node.name } : { op: "pty-slave-open", n: node.pts, noctty: true };
|
|
11378
|
+
return { fd: yield req, file: false };
|
|
11379
|
+
}
|
|
11380
|
+
case "fd":
|
|
11381
|
+
return yield* aliasOf(node.fd, abs, o);
|
|
11382
|
+
case "link":
|
|
11383
|
+
if (node.fd !== void 0) return yield* aliasOf(node.fd, abs, o);
|
|
11384
|
+
throw new JsCallError("EISDIR", abs);
|
|
11385
|
+
case "dir":
|
|
11386
|
+
throw new JsCallError("EISDIR", abs);
|
|
11387
|
+
}
|
|
11388
|
+
}
|
|
11389
|
+
function* devOpen(abs, o) {
|
|
11390
|
+
const write2 = o.write === true || o.append === true || o.truncate === true;
|
|
11391
|
+
return { ...yield* opened(abs, o), read: o.read === true || !write2, write: write2 };
|
|
11392
|
+
}
|
|
11393
|
+
async function devAsync(kernel, step) {
|
|
11394
|
+
let next2 = step.next();
|
|
11395
|
+
while (!next2.done) {
|
|
11396
|
+
let answer2;
|
|
11397
|
+
try {
|
|
11398
|
+
answer2 = { value: await kernel.json(next2.value) };
|
|
11399
|
+
} catch (error) {
|
|
11400
|
+
answer2 = { error };
|
|
11401
|
+
}
|
|
11402
|
+
next2 = "value" in answer2 ? step.next(answer2.value) : step.throw(answer2.error);
|
|
11403
|
+
}
|
|
11404
|
+
return next2.value;
|
|
11405
|
+
}
|
|
11406
|
+
function devSync(kernel, step) {
|
|
11407
|
+
let next2 = step.next();
|
|
11408
|
+
while (!next2.done) {
|
|
11409
|
+
let answer2;
|
|
11410
|
+
try {
|
|
11411
|
+
answer2 = { value: kernel.json(next2.value) };
|
|
11412
|
+
} catch (error) {
|
|
11413
|
+
answer2 = { error };
|
|
11414
|
+
}
|
|
11415
|
+
next2 = "value" in answer2 ? step.next(answer2.value) : step.throw(answer2.error);
|
|
11416
|
+
}
|
|
11417
|
+
return next2.value;
|
|
11418
|
+
}
|
|
11419
|
+
function tooLarge(got) {
|
|
11420
|
+
if (got > DEV_READ_MAX) throw new JsCallError("EFBIG", "readFile");
|
|
11421
|
+
}
|
|
11422
|
+
function liveness(path) {
|
|
11423
|
+
let open = true;
|
|
11424
|
+
return {
|
|
11425
|
+
live: () => {
|
|
11426
|
+
if (!open) throw new JsCallError("EBADF", path);
|
|
11427
|
+
},
|
|
11428
|
+
end: () => {
|
|
11429
|
+
open = false;
|
|
11430
|
+
}
|
|
11431
|
+
};
|
|
11432
|
+
}
|
|
11433
|
+
function allowed(may, what) {
|
|
11434
|
+
if (!may) throw new JsCallError("EBADF", what);
|
|
11435
|
+
}
|
|
11436
|
+
function streamFile(fd, path, io, access) {
|
|
11437
|
+
const { live, end } = liveness(path);
|
|
11438
|
+
const file = {
|
|
11439
|
+
fd,
|
|
11440
|
+
path,
|
|
11441
|
+
async size() {
|
|
11442
|
+
live();
|
|
11443
|
+
return 0;
|
|
11444
|
+
},
|
|
11445
|
+
async read(position, length) {
|
|
11446
|
+
index2(position, "read");
|
|
11447
|
+
index2(length, "read");
|
|
11448
|
+
live();
|
|
11449
|
+
allowed(access.read, "read");
|
|
11450
|
+
return length === 0 ? new Uint8Array(0) : io.read(fd, Math.min(length, MAX_IO));
|
|
11451
|
+
},
|
|
11452
|
+
async write(position, data) {
|
|
11453
|
+
index2(position, "write");
|
|
11454
|
+
live();
|
|
11455
|
+
allowed(access.write, "write");
|
|
11456
|
+
await io.write(fd, data);
|
|
11457
|
+
return data.length;
|
|
11458
|
+
},
|
|
11459
|
+
async truncate(size) {
|
|
11460
|
+
live();
|
|
11461
|
+
index2(size, "truncate");
|
|
11462
|
+
throw new JsCallError("EINVAL", "truncate");
|
|
11463
|
+
},
|
|
11464
|
+
sync: async () => live(),
|
|
11465
|
+
async close() {
|
|
11466
|
+
live();
|
|
11467
|
+
end();
|
|
11468
|
+
await io.close(fd);
|
|
11469
|
+
}
|
|
11470
|
+
};
|
|
11471
|
+
return { file, invalidate: end };
|
|
11472
|
+
}
|
|
11473
|
+
function streamSyncFile(fd, path, io, access) {
|
|
11474
|
+
const { live, end } = liveness(path);
|
|
11475
|
+
const file = {
|
|
11476
|
+
fd,
|
|
11477
|
+
path,
|
|
11478
|
+
size() {
|
|
11479
|
+
live();
|
|
11480
|
+
return 0;
|
|
11481
|
+
},
|
|
11482
|
+
read(position, length) {
|
|
11483
|
+
index2(position, "read");
|
|
11484
|
+
index2(length, "read");
|
|
11485
|
+
live();
|
|
11486
|
+
allowed(access.read, "read");
|
|
11487
|
+
return length === 0 ? new Uint8Array(0) : io.read(fd, Math.min(length, MAX_IO));
|
|
11488
|
+
},
|
|
11489
|
+
write(position, data) {
|
|
11490
|
+
index2(position, "write");
|
|
11491
|
+
live();
|
|
11492
|
+
allowed(access.write, "write");
|
|
11493
|
+
io.write(fd, data);
|
|
11494
|
+
return data.length;
|
|
11495
|
+
},
|
|
11496
|
+
truncate(size) {
|
|
11497
|
+
live();
|
|
11498
|
+
index2(size, "truncate");
|
|
11499
|
+
throw new JsCallError("EINVAL", "truncate");
|
|
11500
|
+
},
|
|
11501
|
+
sync: () => live(),
|
|
11502
|
+
close() {
|
|
11503
|
+
live();
|
|
11504
|
+
end();
|
|
11505
|
+
io.close(fd);
|
|
11506
|
+
}
|
|
11507
|
+
};
|
|
11508
|
+
return { file, invalidate: end };
|
|
11509
|
+
}
|
|
11510
|
+
async function readWhole(file) {
|
|
11511
|
+
try {
|
|
11512
|
+
const parts = [];
|
|
11513
|
+
let got = 0;
|
|
11514
|
+
for (; ; ) {
|
|
11515
|
+
const chunk = await file.read(got, MAX_IO);
|
|
11516
|
+
if (chunk.length === 0) return joined(parts, got);
|
|
11517
|
+
got += chunk.length;
|
|
11518
|
+
tooLarge(got);
|
|
11519
|
+
parts.push(chunk);
|
|
11520
|
+
}
|
|
11521
|
+
} finally {
|
|
11522
|
+
await file.close();
|
|
11523
|
+
}
|
|
11524
|
+
}
|
|
11525
|
+
function readWholeSync(file) {
|
|
11526
|
+
try {
|
|
11527
|
+
const parts = [];
|
|
11528
|
+
let got = 0;
|
|
11529
|
+
for (; ; ) {
|
|
11530
|
+
const chunk = file.read(got, MAX_IO);
|
|
11531
|
+
if (chunk.length === 0) return joined(parts, got);
|
|
11532
|
+
got += chunk.length;
|
|
11533
|
+
tooLarge(got);
|
|
11534
|
+
parts.push(chunk);
|
|
11535
|
+
}
|
|
11536
|
+
} finally {
|
|
11537
|
+
file.close();
|
|
11538
|
+
}
|
|
11539
|
+
}
|
|
11540
|
+
var DEV_READ_MAX, DEVICES2, STDIO3, SELF_FD, S_IFMT2, DIR, LINK, CHAR, BORN;
|
|
11541
|
+
var init_js_dev = __esm({
|
|
11542
|
+
"src/process/js/js-dev.ts"() {
|
|
11543
|
+
"use strict";
|
|
11544
|
+
init_sync_fs_wire();
|
|
11545
|
+
init_js_io();
|
|
11546
|
+
init_js_kernel();
|
|
11547
|
+
DEV_READ_MAX = 64 * 1024 * 1024;
|
|
11548
|
+
DEVICES2 = ["null", "zero", "full", "random", "urandom"];
|
|
11549
|
+
STDIO3 = ["stdin", "stdout", "stderr"];
|
|
11550
|
+
SELF_FD = "/proc/self/fd";
|
|
11551
|
+
S_IFMT2 = 61440;
|
|
11552
|
+
DIR = 16384;
|
|
11553
|
+
LINK = 40960;
|
|
11554
|
+
CHAR = 8192;
|
|
11555
|
+
BORN = Date.now();
|
|
11556
|
+
}
|
|
11557
|
+
});
|
|
11558
|
+
|
|
11103
11559
|
// src/process/js/js-exit.ts
|
|
11104
11560
|
function json(r) {
|
|
11105
11561
|
return r.ok && r.kind === "json" ? r.json : void 0;
|
|
@@ -11112,10 +11568,10 @@ function restoreMode(lane, { terminal, fd, termios }) {
|
|
|
11112
11568
|
lane({ op: "tty-set", fd: at, termios });
|
|
11113
11569
|
return;
|
|
11114
11570
|
}
|
|
11115
|
-
const
|
|
11116
|
-
if (typeof
|
|
11117
|
-
lane({ op: "tty-set", fd:
|
|
11118
|
-
lane({ op: "fd-close", fd:
|
|
11571
|
+
const opened2 = json(lane({ op: "fd-open-tty", name: terminal }));
|
|
11572
|
+
if (typeof opened2 !== "number") return;
|
|
11573
|
+
lane({ op: "tty-set", fd: opened2, termios });
|
|
11574
|
+
lane({ op: "fd-close", fd: opened2 });
|
|
11119
11575
|
}
|
|
11120
11576
|
function writeOut(lane, fd, data) {
|
|
11121
11577
|
let at = 0;
|
|
@@ -11564,7 +12020,7 @@ function netOps(kernel, io) {
|
|
|
11564
12020
|
const r = await kernel.blocking({ op: "sock-resolve", name: host, family: 4 }, signal);
|
|
11565
12021
|
return (r.ok && r.kind === "json" ? r.json : [])[0];
|
|
11566
12022
|
};
|
|
11567
|
-
const
|
|
12023
|
+
const opened2 = async (use) => {
|
|
11568
12024
|
const fd = await kernel.json({ op: "sock-open", domain: "inet" });
|
|
11569
12025
|
try {
|
|
11570
12026
|
return await use(fd);
|
|
@@ -11606,7 +12062,7 @@ function netOps(kernel, io) {
|
|
|
11606
12062
|
};
|
|
11607
12063
|
};
|
|
11608
12064
|
return {
|
|
11609
|
-
listen: (options = {}) =>
|
|
12065
|
+
listen: (options = {}) => opened2(async (fd) => {
|
|
11610
12066
|
const addr = {
|
|
11611
12067
|
family: "inet",
|
|
11612
12068
|
host: options.host ?? "127.0.0.1",
|
|
@@ -11626,7 +12082,7 @@ function netOps(kernel, io) {
|
|
|
11626
12082
|
host: await resolve(host, signal),
|
|
11627
12083
|
port: port(options.port)
|
|
11628
12084
|
};
|
|
11629
|
-
return
|
|
12085
|
+
return opened2(async (fd) => {
|
|
11630
12086
|
const r = await kernel.raw({ op: "sock-connect", fd, addr, nonblock: true });
|
|
11631
12087
|
if (!r.ok && r.errno !== "EINPROGRESS") throw new JsCallError(r.errno, "connect");
|
|
11632
12088
|
await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
|
|
@@ -11660,7 +12116,7 @@ var init_js_net = __esm({
|
|
|
11660
12116
|
// src/process/js/js-run.ts
|
|
11661
12117
|
function stdioOf(how) {
|
|
11662
12118
|
if (how === void 0) return "pipe";
|
|
11663
|
-
if (!
|
|
12119
|
+
if (!STDIO4.has(how)) throw new JsCallError("EINVAL", "run");
|
|
11664
12120
|
return how;
|
|
11665
12121
|
}
|
|
11666
12122
|
function limit(value2) {
|
|
@@ -11708,13 +12164,13 @@ function runSync(kernel, d, o) {
|
|
|
11708
12164
|
});
|
|
11709
12165
|
return decodeRun(bytes, stdout, stderr);
|
|
11710
12166
|
}
|
|
11711
|
-
var encoder2,
|
|
12167
|
+
var encoder2, STDIO4;
|
|
11712
12168
|
var init_js_run = __esm({
|
|
11713
12169
|
"src/process/js/js-run.ts"() {
|
|
11714
12170
|
"use strict";
|
|
11715
12171
|
init_js_kernel();
|
|
11716
12172
|
encoder2 = new TextEncoder();
|
|
11717
|
-
|
|
12173
|
+
STDIO4 = /* @__PURE__ */ new Set(["pipe", "ignore", "inherit"]);
|
|
11718
12174
|
}
|
|
11719
12175
|
});
|
|
11720
12176
|
|
|
@@ -11757,13 +12213,30 @@ function syncOps(kernel, shared) {
|
|
|
11757
12213
|
};
|
|
11758
12214
|
const statOf = (op, path) => {
|
|
11759
12215
|
const abs = resolve(path);
|
|
12216
|
+
if (inDev(abs)) return devSync(kernel, devStat(abs, op === "stat"));
|
|
11760
12217
|
kernel.call({ op: "fd-path-flush", path: abs });
|
|
11761
12218
|
const s = parseSyncFsStat(kernel.json({ op, path: abs }));
|
|
11762
12219
|
if (!s) throw new JsCallError("EIO", op);
|
|
11763
12220
|
return s;
|
|
11764
12221
|
};
|
|
12222
|
+
const openDev2 = (abs, options) => {
|
|
12223
|
+
const { fd, file, ...access } = devSync(kernel, devOpen(abs, options));
|
|
12224
|
+
const forget = () => {
|
|
12225
|
+
infos.delete(fd);
|
|
12226
|
+
handles.delete(fd);
|
|
12227
|
+
};
|
|
12228
|
+
if (file) infos.set(fd, { kind: "file" });
|
|
12229
|
+
const close = (n) => {
|
|
12230
|
+
forget();
|
|
12231
|
+
kernel.call({ op: "fd-close", fd: n });
|
|
12232
|
+
};
|
|
12233
|
+
const handle = file ? syncFile(kernel, fd, abs, options.append === true, forget) : streamSyncFile(fd, abs, { read: (n, max) => read2(n, max), write: write2, close }, access);
|
|
12234
|
+
handles.set(fd, handle.invalidate);
|
|
12235
|
+
return handle.file;
|
|
12236
|
+
};
|
|
11765
12237
|
const open = (path, options = {}) => {
|
|
11766
12238
|
const abs = resolve(path);
|
|
12239
|
+
if (inDev(abs)) return openDev2(abs, options);
|
|
11767
12240
|
let existing;
|
|
11768
12241
|
try {
|
|
11769
12242
|
existing = statOf(isExclusive(options) ? "lstat" : "stat", abs);
|
|
@@ -11867,17 +12340,30 @@ function syncPathOps(kernel, resolve, statOf, open) {
|
|
|
11867
12340
|
return {
|
|
11868
12341
|
stat: (path) => statOf("stat", path),
|
|
11869
12342
|
lstat: (path) => statOf("lstat", path),
|
|
11870
|
-
exists
|
|
11871
|
-
|
|
12343
|
+
exists(path) {
|
|
12344
|
+
const abs = resolve(path);
|
|
12345
|
+
if (inDev(abs)) return devSync(kernel, devExists(abs));
|
|
12346
|
+
return kernel.json({ op: "exists", path: abs }) === true;
|
|
12347
|
+
},
|
|
12348
|
+
readdir(path) {
|
|
12349
|
+
const abs = resolve(path);
|
|
12350
|
+
if (inDev(abs)) return devSync(kernel, devReaddir(abs));
|
|
12351
|
+
return kernel.json({ op: "readdir", path: abs });
|
|
12352
|
+
},
|
|
11872
12353
|
mkdir: (path) => void kernel.call({ op: "mkdir", path: resolve(path) }),
|
|
11873
12354
|
rm: (path) => void kernel.call({ op: "rm", path: resolve(path) }),
|
|
11874
12355
|
unlink: (path) => void kernel.call({ op: "unlink", path: resolve(path) }),
|
|
11875
12356
|
rename: (from, to) => void kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
|
|
11876
12357
|
link: (from, to) => void kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
|
|
11877
12358
|
symlink: (target, path) => void kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
|
|
11878
|
-
readlink
|
|
12359
|
+
readlink(path) {
|
|
12360
|
+
const abs = resolve(path);
|
|
12361
|
+
if (inDev(abs)) return devSync(kernel, devReadlink(abs));
|
|
12362
|
+
return String(kernel.json({ op: "readlink", path: abs }));
|
|
12363
|
+
},
|
|
11879
12364
|
readFile(path) {
|
|
11880
12365
|
const abs = resolve(path);
|
|
12366
|
+
if (inDev(abs)) return readWholeSync(open(abs));
|
|
11881
12367
|
kernel.call({ op: "fd-path-flush", path: abs });
|
|
11882
12368
|
return kernel.bytes({ op: "read", path: abs });
|
|
11883
12369
|
},
|
|
@@ -11898,6 +12384,7 @@ var init_js_sync = __esm({
|
|
|
11898
12384
|
init_signals();
|
|
11899
12385
|
init_sync_fs_wire();
|
|
11900
12386
|
init_sync_sab_bridge();
|
|
12387
|
+
init_js_dev();
|
|
11901
12388
|
init_js_io();
|
|
11902
12389
|
init_js_kernel();
|
|
11903
12390
|
encoder3 = new TextEncoder();
|
|
@@ -12298,6 +12785,7 @@ function createContext(o) {
|
|
|
12298
12785
|
const writable2 = (fd) => new WritableStream({ write: (chunk) => write2(fd, chunk) });
|
|
12299
12786
|
const statOf = async (op, path) => {
|
|
12300
12787
|
const abs = resolve(path);
|
|
12788
|
+
if (inDev(abs)) return devAsync(kernel, devStat(abs, op === "stat"));
|
|
12301
12789
|
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
12302
12790
|
const s = parseSyncFsStat(await kernel.json({ op, path: abs }));
|
|
12303
12791
|
if (!s) throw new JsCallError("EIO", op);
|
|
@@ -12305,6 +12793,7 @@ function createContext(o) {
|
|
|
12305
12793
|
};
|
|
12306
12794
|
const open = async (path, options = {}) => {
|
|
12307
12795
|
const abs = resolve(path);
|
|
12796
|
+
if (inDev(abs)) return openDev(kernel, abs, options, { infos, handles, read: read2, write: writeAll });
|
|
12308
12797
|
const existing = await statOf(isExclusive(options) ? "lstat" : "stat", abs).catch(absent);
|
|
12309
12798
|
checkOpen(abs, options, existing);
|
|
12310
12799
|
const fd = await kernel.json(openRequest(abs, options));
|
|
@@ -12324,6 +12813,7 @@ function createContext(o) {
|
|
|
12324
12813
|
};
|
|
12325
12814
|
const fs = pathOps(kernel, resolve, statOf, open);
|
|
12326
12815
|
const lane = o.lane ?? laneOf(void 0);
|
|
12816
|
+
if (o.lane) kernel.syncLane = o.lane;
|
|
12327
12817
|
const syncKernel = new JsSyncKernel(lane, kernel, unwind);
|
|
12328
12818
|
const terminal = ttyOps(kernel);
|
|
12329
12819
|
const sync = {
|
|
@@ -12404,6 +12894,26 @@ function createContext(o) {
|
|
|
12404
12894
|
};
|
|
12405
12895
|
return { ctx, drain: drain2 };
|
|
12406
12896
|
}
|
|
12897
|
+
async function openDev(kernel, abs, options, state) {
|
|
12898
|
+
const { fd, file, ...access } = await devAsync(kernel, devOpen(abs, options));
|
|
12899
|
+
const forget = () => {
|
|
12900
|
+
state.infos.delete(fd);
|
|
12901
|
+
state.handles.delete(fd);
|
|
12902
|
+
};
|
|
12903
|
+
if (file) state.infos.set(fd, { kind: "file" });
|
|
12904
|
+
const close = async (n) => {
|
|
12905
|
+
forget();
|
|
12906
|
+
await kernel.call({ op: "fd-close", fd: n });
|
|
12907
|
+
};
|
|
12908
|
+
const handle = file ? fileHandle(kernel, fd, abs, options.append === true, forget) : streamFile(
|
|
12909
|
+
fd,
|
|
12910
|
+
abs,
|
|
12911
|
+
{ read: (n, max) => state.read(n, max), write: state.write, close },
|
|
12912
|
+
access
|
|
12913
|
+
);
|
|
12914
|
+
state.handles.set(fd, handle.invalidate);
|
|
12915
|
+
return handle.file;
|
|
12916
|
+
}
|
|
12407
12917
|
function fileHandle(kernel, fd, path, append, forget) {
|
|
12408
12918
|
let open = true;
|
|
12409
12919
|
const live = () => {
|
|
@@ -12496,17 +13006,30 @@ function pathOps(kernel, resolve, statOf, open) {
|
|
|
12496
13006
|
return {
|
|
12497
13007
|
stat: (path) => statOf("stat", path),
|
|
12498
13008
|
lstat: (path) => statOf("lstat", path),
|
|
12499
|
-
|
|
12500
|
-
|
|
13009
|
+
async exists(path) {
|
|
13010
|
+
const abs = resolve(path);
|
|
13011
|
+
if (inDev(abs)) return devAsync(kernel, devExists(abs));
|
|
13012
|
+
return await kernel.json({ op: "exists", path: abs }) === true;
|
|
13013
|
+
},
|
|
13014
|
+
async readdir(path) {
|
|
13015
|
+
const abs = resolve(path);
|
|
13016
|
+
if (inDev(abs)) return devAsync(kernel, devReaddir(abs));
|
|
13017
|
+
return await kernel.json({ op: "readdir", path: abs });
|
|
13018
|
+
},
|
|
12501
13019
|
mkdir: async (path) => void await kernel.call({ op: "mkdir", path: resolve(path) }),
|
|
12502
13020
|
rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
|
|
12503
13021
|
unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
|
|
12504
13022
|
rename: async (from, to) => void await kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
|
|
12505
13023
|
link: async (from, to) => void await kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
|
|
12506
13024
|
symlink: async (target, path) => void await kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
|
|
12507
|
-
|
|
13025
|
+
async readlink(path) {
|
|
13026
|
+
const abs = resolve(path);
|
|
13027
|
+
if (inDev(abs)) return devAsync(kernel, devReadlink(abs));
|
|
13028
|
+
return String(await kernel.json({ op: "readlink", path: abs }));
|
|
13029
|
+
},
|
|
12508
13030
|
async readFile(path) {
|
|
12509
13031
|
const abs = resolve(path);
|
|
13032
|
+
if (inDev(abs)) return readWhole(await open(abs));
|
|
12510
13033
|
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
12511
13034
|
return kernel.bytes({ op: "read", path: abs });
|
|
12512
13035
|
},
|
|
@@ -12527,6 +13050,7 @@ var init_js_context = __esm({
|
|
|
12527
13050
|
init_signals();
|
|
12528
13051
|
init_sync_fs_wire();
|
|
12529
13052
|
init_js_children();
|
|
13053
|
+
init_js_dev();
|
|
12530
13054
|
init_js_exit();
|
|
12531
13055
|
init_js_fetch();
|
|
12532
13056
|
init_js_io();
|