@ai-ecoverse/slicc-kernel 1.85.1 → 1.87.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 +20 -12
- package/dist/index.js +1 -0
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +141 -40
- package/dist/kernel-worker.js.map +3 -3
- package/dist/meta.js +384 -0
- package/dist/meta.js.map +7 -0
- package/dist/node-process-worker.js +153 -61
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +118 -40
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +153 -61
- package/dist/process-worker.js.map +3 -3
- package/package.json +3 -2
package/dist/process-worker.js
CHANGED
|
@@ -1112,10 +1112,14 @@ function liveNodePath(node) {
|
|
|
1112
1112
|
const root = node.mount.opts.root.replace(/\/+$/, "");
|
|
1113
1113
|
return parts.length === 0 ? root || "/" : `${root}/${parts.reverse().join("/")}`;
|
|
1114
1114
|
}
|
|
1115
|
-
function
|
|
1115
|
+
function exactIn(node) {
|
|
1116
|
+
return node?.mount.opts.bridge.owners === true;
|
|
1117
|
+
}
|
|
1118
|
+
function modeFromStat(st, exact = false) {
|
|
1116
1119
|
const type = st.isSymbolicLink ? S_IFLNK : st.isDirectory ? S_IFDIR : S_IFREG;
|
|
1117
1120
|
const fallback = st.isDirectory || st.isSymbolicLink ? 511 : 438;
|
|
1118
|
-
|
|
1121
|
+
const perm = (st.mode ?? fallback) & PERM_MASK;
|
|
1122
|
+
return type | (exact ? perm : perm || fallback);
|
|
1119
1123
|
}
|
|
1120
1124
|
function toMs(v) {
|
|
1121
1125
|
if (v === void 0 || v === null) return void 0;
|
|
@@ -1223,7 +1227,7 @@ function createHelpers(Fs, ops) {
|
|
|
1223
1227
|
return { ...stat ? { stat, statAt } : {}, len: 0, loaded: false, dirty: false, openCount: 0 };
|
|
1224
1228
|
}
|
|
1225
1229
|
function makeNode(parent, name2, st) {
|
|
1226
|
-
const node = Fs.createNode(parent, name2, modeFromStat(st), 0);
|
|
1230
|
+
const node = Fs.createNode(parent, name2, modeFromStat(st, exactIn(parent)), 0);
|
|
1227
1231
|
node.node_ops = ops.node;
|
|
1228
1232
|
node.stream_ops = ops.stream;
|
|
1229
1233
|
node.live = freshState(st);
|
|
@@ -1237,7 +1241,7 @@ function createHelpers(Fs, ops) {
|
|
|
1237
1241
|
if (!cachedStat(node.live, Fs.isDir(node.mode))) {
|
|
1238
1242
|
const st = call2(() => bridgeOf(node).lstat(liveNodePath(linked.holder(node))));
|
|
1239
1243
|
Object.assign(node.live, { stat: st, statAt: syncCallCount() });
|
|
1240
|
-
node.mode = modeFromStat(st);
|
|
1244
|
+
node.mode = modeFromStat(st, exactIn(node));
|
|
1241
1245
|
}
|
|
1242
1246
|
return node.live.stat;
|
|
1243
1247
|
}
|
|
@@ -1575,9 +1579,21 @@ function createStreamOps(h) {
|
|
|
1575
1579
|
}
|
|
1576
1580
|
return want;
|
|
1577
1581
|
};
|
|
1582
|
+
const directory = (stream) => {
|
|
1583
|
+
const bridge = bridgeOf(stream.node);
|
|
1584
|
+
if (!bridge.owners || !Fs.isDir(stream.node.mode) || stream.flags & O_PATH) return;
|
|
1585
|
+
try {
|
|
1586
|
+
h.call(
|
|
1587
|
+
() => bridge.access?.(liveNodePath(stream.node), accessOf(wantOf(stream.flags)), "open")
|
|
1588
|
+
);
|
|
1589
|
+
} catch (err) {
|
|
1590
|
+
if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
|
|
1591
|
+
throw err;
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1578
1594
|
return {
|
|
1579
1595
|
open(stream) {
|
|
1580
|
-
if (!Fs.isFile(stream.node.mode)) return;
|
|
1596
|
+
if (!Fs.isFile(stream.node.mode)) return directory(stream);
|
|
1581
1597
|
const s = stream.node.live;
|
|
1582
1598
|
const created = s.created === true;
|
|
1583
1599
|
s.created = void 0;
|
|
@@ -1709,6 +1725,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
1709
1725
|
const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
|
|
1710
1726
|
if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
|
|
1711
1727
|
const root = h.makeNode(null, "/", st);
|
|
1728
|
+
root.mode = modeFromStat(st, mount.opts.bridge.owners === true);
|
|
1712
1729
|
mounts.add(mount);
|
|
1713
1730
|
return root;
|
|
1714
1731
|
}
|
|
@@ -1918,7 +1935,7 @@ function useLiveChown(Fs) {
|
|
|
1918
1935
|
Fs.chown(target, uid, gid);
|
|
1919
1936
|
};
|
|
1920
1937
|
}
|
|
1921
|
-
var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_ACCMODE, O_TRUNC, stale;
|
|
1938
|
+
var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_ACCMODE, O_TRUNC, O_PATH, stale;
|
|
1922
1939
|
var init_live_vfs_fs = __esm({
|
|
1923
1940
|
"src/realm/live-vfs-fs.ts"() {
|
|
1924
1941
|
"use strict";
|
|
@@ -1938,6 +1955,7 @@ var init_live_vfs_fs = __esm({
|
|
|
1938
1955
|
EARLY_WHOLE_FILE = 64 * 1024;
|
|
1939
1956
|
O_ACCMODE = 3;
|
|
1940
1957
|
O_TRUNC = 512;
|
|
1958
|
+
O_PATH = 2097152;
|
|
1941
1959
|
stale = (s) => !!s.orphan && !s.kept;
|
|
1942
1960
|
}
|
|
1943
1961
|
});
|
|
@@ -2360,7 +2378,7 @@ var init_kernel_streams = __esm({
|
|
|
2360
2378
|
openSealed(open, path, flags, mode) {
|
|
2361
2379
|
const { openSealed } = this.sys;
|
|
2362
2380
|
if (path !== SEALED_PATH || !openSealed) return void 0;
|
|
2363
|
-
const kfd = this.call(() => openSealed.call(this.sys));
|
|
2381
|
+
const kfd = this.call(() => openSealed.call(this.sys, flags & 3));
|
|
2364
2382
|
return this.vessel(open, kfd, { path, flags, mode }, false);
|
|
2365
2383
|
}
|
|
2366
2384
|
openClipboard(open, path, flags, mode) {
|
|
@@ -2757,7 +2775,7 @@ function pathOpensLinks(Fs) {
|
|
|
2757
2775
|
const fs = Fs;
|
|
2758
2776
|
const { mayOpen, isLink } = fs;
|
|
2759
2777
|
if (!mayOpen || !isLink) return;
|
|
2760
|
-
fs.mayOpen = (node, flags) => flags &
|
|
2778
|
+
fs.mayOpen = (node, flags) => flags & O_PATH2 && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
|
|
2761
2779
|
}
|
|
2762
2780
|
function importKey(namespace, name2, glue) {
|
|
2763
2781
|
const own = glue?.[name2];
|
|
@@ -3237,7 +3255,24 @@ function kernelAccess(imports, fs, memory, glue) {
|
|
|
3237
3255
|
}
|
|
3238
3256
|
});
|
|
3239
3257
|
}
|
|
3258
|
+
function kernelChdir(Fs) {
|
|
3259
|
+
const { chdir, lookupPath, ErrnoError } = Fs;
|
|
3260
|
+
if (!chdir || !lookupPath || !ErrnoError) return;
|
|
3261
|
+
Fs.chdir = (path) => {
|
|
3262
|
+
const { node } = lookupPath.call(Fs, path, { follow: true });
|
|
3263
|
+
const directory = Fs.isDir?.(node.mode) === true;
|
|
3264
|
+
const bridge = node.live && directory ? node.mount.opts.bridge : void 0;
|
|
3265
|
+
try {
|
|
3266
|
+
bridge?.access?.(liveNodePath(node), X_ACCESS, "eaccess", false);
|
|
3267
|
+
} catch (err) {
|
|
3268
|
+
throw new ErrnoError(errnoOf(err));
|
|
3269
|
+
}
|
|
3270
|
+
chdir.call(Fs, path);
|
|
3271
|
+
};
|
|
3272
|
+
}
|
|
3240
3273
|
function linuxDevices(Fs) {
|
|
3274
|
+
Fs.ignorePermissions = true;
|
|
3275
|
+
kernelChdir(Fs);
|
|
3241
3276
|
const { chmod } = Fs;
|
|
3242
3277
|
if (!chmod) return;
|
|
3243
3278
|
for (const [path, mode] of DEVICE_MODES) {
|
|
@@ -3247,7 +3282,7 @@ function linuxDevices(Fs) {
|
|
|
3247
3282
|
}
|
|
3248
3283
|
}
|
|
3249
3284
|
}
|
|
3250
|
-
var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, AT_SYMLINK_NOFOLLOW, EMSCRIPTEN_EPERM,
|
|
3285
|
+
var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, AT_SYMLINK_NOFOLLOW, EMSCRIPTEN_EPERM, O_PATH2, LITERALS, UTIME_NOW, UTIME_OMIT, PROT_WRITE, MAP_PRIVATE, MAP_TYPE, O_WRONLY, MAP_ALIGN, DIR_MODE, LINK_MODE, CHAR_DEVICE, O_ACCMODE2, O_CREAT2, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS, W_ACCESS, X_ACCESS, DEVICE_MODES;
|
|
3251
3286
|
var init_process_fds = __esm({
|
|
3252
3287
|
"src/process/process-fds.ts"() {
|
|
3253
3288
|
"use strict";
|
|
@@ -3275,7 +3310,7 @@ var init_process_fds = __esm({
|
|
|
3275
3310
|
EBADF = 8;
|
|
3276
3311
|
AT_SYMLINK_NOFOLLOW = 256;
|
|
3277
3312
|
EMSCRIPTEN_EPERM = 63;
|
|
3278
|
-
|
|
3313
|
+
O_PATH2 = 2097152;
|
|
3279
3314
|
LITERALS = {
|
|
3280
3315
|
openat: "__syscall_openat",
|
|
3281
3316
|
mkdirat: "__syscall_mkdirat",
|
|
@@ -3307,6 +3342,7 @@ var init_process_fds = __esm({
|
|
|
3307
3342
|
AT_FDCWD = -100;
|
|
3308
3343
|
AT_EACCESS = 512;
|
|
3309
3344
|
W_ACCESS = 2;
|
|
3345
|
+
X_ACCESS = 1;
|
|
3310
3346
|
DEVICE_MODES = [
|
|
3311
3347
|
["/", 493],
|
|
3312
3348
|
["/dev", 493],
|
|
@@ -3397,8 +3433,8 @@ function describeInherited(Fs, sys, streams, livePath, actions = []) {
|
|
|
3397
3433
|
const out = [];
|
|
3398
3434
|
for (const [fd, stream] of slots3) {
|
|
3399
3435
|
promote(stream);
|
|
3400
|
-
const
|
|
3401
|
-
if (
|
|
3436
|
+
const slot2 = inheritedSlot(fd, stream);
|
|
3437
|
+
if (slot2) out.push(slot2);
|
|
3402
3438
|
}
|
|
3403
3439
|
return out;
|
|
3404
3440
|
}
|
|
@@ -3616,7 +3652,7 @@ function createProcessKernel(deps) {
|
|
|
3616
3652
|
const reaped = /* @__PURE__ */ new Map();
|
|
3617
3653
|
const call2 = (req, label) => transport.call(req, Infinity, label);
|
|
3618
3654
|
const at = (path) => path === "" || path.startsWith("/") ? path : `${Fs.cwd()}/${path}`;
|
|
3619
|
-
const
|
|
3655
|
+
const slot2 = (fd, n, promote) => {
|
|
3620
3656
|
const stream = fd >= 0 ? Fs.getStream(fd) : null;
|
|
3621
3657
|
if (!stream) return { none: true };
|
|
3622
3658
|
promote?.(stream);
|
|
@@ -3665,7 +3701,7 @@ function createProcessKernel(deps) {
|
|
|
3665
3701
|
const unflushed = flushed(deps.beforeSpawn);
|
|
3666
3702
|
if (unflushed < 0) return unflushed;
|
|
3667
3703
|
const promote = deps.stdioPromoter?.();
|
|
3668
|
-
const stdio = [0, 1, 2].map((n) =>
|
|
3704
|
+
const stdio = [0, 1, 2].map((n) => slot2(fds[n] ?? -1, n, promote));
|
|
3669
3705
|
const inherit = deps.inherit?.(actions) ?? [];
|
|
3670
3706
|
const req = {
|
|
3671
3707
|
op: "proc-spawn",
|
|
@@ -4609,8 +4645,8 @@ function kernelSys(transport) {
|
|
|
4609
4645
|
openPts(n, noctty) {
|
|
4610
4646
|
return json2(call2({ op: "pty-slave-open", n, noctty }, `pty-slave-open ${n}`));
|
|
4611
4647
|
},
|
|
4612
|
-
openSealed() {
|
|
4613
|
-
return json2(call2({ op: "fd-open-sealed" }, "fd-open-sealed"));
|
|
4648
|
+
openSealed(flags) {
|
|
4649
|
+
return json2(call2({ op: "fd-open-sealed", flags }, "fd-open-sealed"));
|
|
4614
4650
|
},
|
|
4615
4651
|
openClipboard(flags) {
|
|
4616
4652
|
return json2(call2({ op: "fd-open-clipboard", flags }, "fd-open-clipboard"));
|
|
@@ -6297,12 +6333,10 @@ var init_wasi_fds = __esm({
|
|
|
6297
6333
|
let fd;
|
|
6298
6334
|
let kind;
|
|
6299
6335
|
if (path === SEALED_PATH2 && openSealed) {
|
|
6300
|
-
|
|
6301
|
-
if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
|
|
6302
|
-
fd = openSealed.call(this.kernel.sys);
|
|
6336
|
+
fd = this.openCharDevice(openSealed, oflags, rights);
|
|
6303
6337
|
kind = "sealed";
|
|
6304
6338
|
} else if (path === CLIPBOARD_PATH2 && openClipboard) {
|
|
6305
|
-
fd = this.
|
|
6339
|
+
fd = this.openCharDevice(openClipboard, oflags, rights);
|
|
6306
6340
|
kind = "clipboard";
|
|
6307
6341
|
} else if (path === "/dev/tty" || /^\/dev\/tty\d+$/.test(path)) {
|
|
6308
6342
|
fd = openTty?.call(this.kernel.sys, path === "/dev/tty" ? void 0 : path);
|
|
@@ -6313,12 +6347,12 @@ var init_wasi_fds = __esm({
|
|
|
6313
6347
|
this.bump();
|
|
6314
6348
|
return fd;
|
|
6315
6349
|
}
|
|
6316
|
-
|
|
6350
|
+
openCharDevice(openDevice2, oflags, rights) {
|
|
6317
6351
|
if (oflags & OFLAGS.DIRECTORY) throw new WasiError("ENOTDIR");
|
|
6318
6352
|
if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
|
|
6319
6353
|
const want = wantOf2(oflags, rights);
|
|
6320
6354
|
const flags = want === 6 ? O_RDWR4 : want === 2 ? O_WRONLY4 : 0;
|
|
6321
|
-
return
|
|
6355
|
+
return openDevice2.call(this.kernel.sys, flags);
|
|
6322
6356
|
}
|
|
6323
6357
|
open(path, oflags, rights, fdflags) {
|
|
6324
6358
|
const device2 = deviceOf(path);
|
|
@@ -6904,7 +6938,7 @@ var init_wasi_host = __esm({
|
|
|
6904
6938
|
}
|
|
6905
6939
|
return path;
|
|
6906
6940
|
};
|
|
6907
|
-
const
|
|
6941
|
+
const modeOf2 = (st) => (st.mode ?? 0) & 4095;
|
|
6908
6942
|
const chown = (path, uid, gid, follow2) => {
|
|
6909
6943
|
const { chown: own } = this.o.fs;
|
|
6910
6944
|
if (!own) throw new WasiError("ENOSYS");
|
|
@@ -6983,7 +7017,7 @@ var init_wasi_host = __esm({
|
|
|
6983
7017
|
fd_mode: (fd, out) => {
|
|
6984
7018
|
const e = fds.get(fd);
|
|
6985
7019
|
const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
|
|
6986
|
-
const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE :
|
|
7020
|
+
const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf2(this.o.fs.stat(pathOf(fd)));
|
|
6987
7021
|
mem.view().setUint32(out, mode, true);
|
|
6988
7022
|
},
|
|
6989
7023
|
path_mode: (dirfd, p, l, flags, out) => {
|
|
@@ -6991,7 +7025,7 @@ var init_wasi_host = __esm({
|
|
|
6991
7025
|
if (this.synthetic(path) && deviceOf(path) === void 0)
|
|
6992
7026
|
return void mem.view().setUint32(out, SEALED_MODE, true);
|
|
6993
7027
|
const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
|
|
6994
|
-
mem.view().setUint32(out,
|
|
7028
|
+
mem.view().setUint32(out, modeOf2(st), true);
|
|
6995
7029
|
}
|
|
6996
7030
|
});
|
|
6997
7031
|
}
|
|
@@ -8005,7 +8039,7 @@ function importsContext({
|
|
|
8005
8039
|
}
|
|
8006
8040
|
function processes(host, call2, inThread) {
|
|
8007
8041
|
const close = (fd) => void call2({ op: "fd-close", fd });
|
|
8008
|
-
const
|
|
8042
|
+
const slot2 = (n, how, mine, theirs) => {
|
|
8009
8043
|
if (how === "inherit") return { fd: n };
|
|
8010
8044
|
if (how === "null") return { none: true };
|
|
8011
8045
|
const [read2, write2] = call2({ op: "fd-pipe" });
|
|
@@ -8019,7 +8053,7 @@ function processes(host, call2, inThread) {
|
|
|
8019
8053
|
const theirs = [];
|
|
8020
8054
|
host.fds.promoteFiles();
|
|
8021
8055
|
try {
|
|
8022
|
-
const stdio = STDIO.map((name2, n) =>
|
|
8056
|
+
const stdio = STDIO.map((name2, n) => slot2(n, o[name2] ?? "inherit", mine, theirs));
|
|
8023
8057
|
const req = {
|
|
8024
8058
|
op: "proc-spawn",
|
|
8025
8059
|
file: o.argv[0],
|
|
@@ -11088,6 +11122,12 @@ var init_async_sab = __esm({
|
|
|
11088
11122
|
});
|
|
11089
11123
|
|
|
11090
11124
|
// src/process/js/js-kernel.ts
|
|
11125
|
+
function modeOf(mode) {
|
|
11126
|
+
if (!Number.isInteger(mode) || mode < 0 || mode > 4095) {
|
|
11127
|
+
throw new JsCallError("EINVAL", "chmod");
|
|
11128
|
+
}
|
|
11129
|
+
return mode;
|
|
11130
|
+
}
|
|
11091
11131
|
function callError(result, op) {
|
|
11092
11132
|
const { errno: errno2, message: message2 } = result;
|
|
11093
11133
|
const detailed = typeof message2 === "string" && message2 !== errno2 && DETAILED.has(op);
|
|
@@ -11341,7 +11381,7 @@ function writable(io, fd) {
|
|
|
11341
11381
|
abort: () => io.close(fd)
|
|
11342
11382
|
});
|
|
11343
11383
|
}
|
|
11344
|
-
function childOps(kernel, io, defaults) {
|
|
11384
|
+
function childOps(kernel, io, defaults, sync) {
|
|
11345
11385
|
const wait2 = async (pid) => {
|
|
11346
11386
|
const r = await kernel.blocking({ op: "proc-wait", pid, nohang: false });
|
|
11347
11387
|
const [, status2] = r.ok && r.kind === "json" ? r.json : [0, 0];
|
|
@@ -11361,25 +11401,43 @@ function childOps(kernel, io, defaults) {
|
|
|
11361
11401
|
kill: (signal) => kill(pid, signal)
|
|
11362
11402
|
};
|
|
11363
11403
|
};
|
|
11364
|
-
const
|
|
11404
|
+
const request = (o) => {
|
|
11365
11405
|
const [file] = o.argv;
|
|
11366
11406
|
if (file === void 0) throw new JsCallError("EINVAL", "spawn");
|
|
11367
11407
|
const group = groupOf(o, "spawn");
|
|
11368
11408
|
const named = argv0Of(o.argv0, "spawn");
|
|
11409
|
+
return (stdio) => ({
|
|
11410
|
+
op: "proc-spawn",
|
|
11411
|
+
file,
|
|
11412
|
+
argv: [...o.argv],
|
|
11413
|
+
...named,
|
|
11414
|
+
env: { ...o.env ?? defaults.env },
|
|
11415
|
+
cwd: o.cwd ?? defaults.cwd,
|
|
11416
|
+
stdio,
|
|
11417
|
+
...group
|
|
11418
|
+
});
|
|
11419
|
+
};
|
|
11420
|
+
const spawnSync = (o) => {
|
|
11421
|
+
const spawning = request(o);
|
|
11422
|
+
const mine = [];
|
|
11423
|
+
const theirs = [];
|
|
11424
|
+
try {
|
|
11425
|
+
const stdio = slotsSync(sync, o, mine, theirs);
|
|
11426
|
+
return childOf(sync.json(spawning(stdio)), mine);
|
|
11427
|
+
} catch (err) {
|
|
11428
|
+
closeAllSync(sync, mine);
|
|
11429
|
+
throw err;
|
|
11430
|
+
} finally {
|
|
11431
|
+
closeAllSync(sync, theirs);
|
|
11432
|
+
}
|
|
11433
|
+
};
|
|
11434
|
+
const spawn = async (o) => {
|
|
11435
|
+
const spawning = request(o);
|
|
11369
11436
|
const mine = [];
|
|
11370
11437
|
const theirs = [];
|
|
11371
11438
|
try {
|
|
11372
11439
|
const stdio = await slots2(kernel, o, mine, theirs);
|
|
11373
|
-
const pid = await kernel.json(
|
|
11374
|
-
op: "proc-spawn",
|
|
11375
|
-
file,
|
|
11376
|
-
argv: [...o.argv],
|
|
11377
|
-
...named,
|
|
11378
|
-
env: { ...o.env ?? defaults.env },
|
|
11379
|
-
cwd: o.cwd ?? defaults.cwd,
|
|
11380
|
-
stdio,
|
|
11381
|
-
...group
|
|
11382
|
-
});
|
|
11440
|
+
const pid = await kernel.json(spawning(stdio));
|
|
11383
11441
|
return childOf(pid, mine);
|
|
11384
11442
|
} catch (err) {
|
|
11385
11443
|
await closeAll(io, mine);
|
|
@@ -11388,7 +11446,7 @@ function childOps(kernel, io, defaults) {
|
|
|
11388
11446
|
await closeAll(io, theirs);
|
|
11389
11447
|
}
|
|
11390
11448
|
};
|
|
11391
|
-
return { spawn, wait: wait2, kill };
|
|
11449
|
+
return { spawn, wait: wait2, kill, spawnSync };
|
|
11392
11450
|
}
|
|
11393
11451
|
function groupOf(o, call2) {
|
|
11394
11452
|
const { pgid, session } = o;
|
|
@@ -11407,27 +11465,43 @@ function argv0Of(argv0, call2) {
|
|
|
11407
11465
|
async function closeAll(io, fds) {
|
|
11408
11466
|
for (const fd of fds) if (fd !== void 0) await io.close(fd).catch(() => void 0);
|
|
11409
11467
|
}
|
|
11410
|
-
|
|
11468
|
+
function closeAllSync(sync, fds) {
|
|
11469
|
+
for (const fd of fds) if (fd !== void 0) sync.raw({ op: "fd-close", fd });
|
|
11470
|
+
}
|
|
11471
|
+
function checked(hows) {
|
|
11472
|
+
const fds = [];
|
|
11411
11473
|
for (const [n, how] of hows.entries()) {
|
|
11412
11474
|
if (how === "pipe" || how === "null") continue;
|
|
11413
11475
|
if (how !== "inherit" && typeof how !== "number") throw new JsCallError("EINVAL", "spawn");
|
|
11414
|
-
|
|
11476
|
+
fds.push(how === "inherit" ? n : how);
|
|
11415
11477
|
}
|
|
11478
|
+
return fds;
|
|
11479
|
+
}
|
|
11480
|
+
async function preflight(kernel, hows) {
|
|
11481
|
+
for (const fd of checked(hows)) await kernel.json({ op: "fd-info", fd });
|
|
11482
|
+
}
|
|
11483
|
+
function slot(n, how, pipe, mine, theirs) {
|
|
11484
|
+
if (how === "inherit") return { fd: n };
|
|
11485
|
+
if (how === "null") return { none: true };
|
|
11486
|
+
if (typeof how === "number") return { fd: how };
|
|
11487
|
+
const [read2, write2] = pipe();
|
|
11488
|
+
mine[n] = n === 0 ? write2 : read2;
|
|
11489
|
+
theirs.push(n === 0 ? read2 : write2);
|
|
11490
|
+
return { fd: n === 0 ? read2 : write2 };
|
|
11491
|
+
}
|
|
11492
|
+
function slotsSync(sync, o, mine, theirs) {
|
|
11493
|
+
const hows = STDIO2.map((name2) => o[name2] ?? "inherit");
|
|
11494
|
+
for (const fd of checked(hows)) sync.json({ op: "fd-info", fd });
|
|
11495
|
+
const pipe = () => sync.json({ op: "fd-pipe" });
|
|
11496
|
+
return hows.map((how, n) => slot(n, how, pipe, mine, theirs));
|
|
11416
11497
|
}
|
|
11417
11498
|
async function slots2(kernel, o, mine, theirs) {
|
|
11418
11499
|
const hows = STDIO2.map((name2) => o[name2] ?? "inherit");
|
|
11419
11500
|
await preflight(kernel, hows);
|
|
11420
11501
|
const stdio = [];
|
|
11421
11502
|
for (const [n, how] of hows.entries()) {
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
else if (typeof how === "number") stdio.push({ fd: how });
|
|
11425
|
-
else {
|
|
11426
|
-
const [read2, write2] = await kernel.json({ op: "fd-pipe" });
|
|
11427
|
-
mine[n] = n === 0 ? write2 : read2;
|
|
11428
|
-
theirs.push(n === 0 ? read2 : write2);
|
|
11429
|
-
stdio.push({ fd: n === 0 ? read2 : write2 });
|
|
11430
|
-
}
|
|
11503
|
+
const pair = how === "pipe" ? await kernel.json({ op: "fd-pipe" }) : [];
|
|
11504
|
+
stdio.push(slot(n, how, () => pair, mine, theirs));
|
|
11431
11505
|
}
|
|
11432
11506
|
return stdio;
|
|
11433
11507
|
}
|
|
@@ -11693,6 +11767,10 @@ function* aliasOf(fd, abs, o) {
|
|
|
11693
11767
|
}
|
|
11694
11768
|
return { fd: copy2, file };
|
|
11695
11769
|
}
|
|
11770
|
+
function accessFlags(o) {
|
|
11771
|
+
const write2 = o.write === true || o.append === true || o.truncate === true;
|
|
11772
|
+
return write2 ? o.read === true ? 2 : 1 : 0;
|
|
11773
|
+
}
|
|
11696
11774
|
function* opened(abs, o) {
|
|
11697
11775
|
const node = yield* lookup(abs);
|
|
11698
11776
|
if (isExclusive(o)) throw new JsCallError("EEXIST", abs);
|
|
@@ -11701,13 +11779,13 @@ function* opened(abs, o) {
|
|
|
11701
11779
|
return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
|
|
11702
11780
|
case "tty":
|
|
11703
11781
|
return { fd: yield { op: "fd-open-tty" }, file: false };
|
|
11704
|
-
case "clipboard":
|
|
11705
|
-
|
|
11706
|
-
|
|
11707
|
-
|
|
11708
|
-
|
|
11782
|
+
case "clipboard":
|
|
11783
|
+
return {
|
|
11784
|
+
fd: yield { op: "fd-open-clipboard", flags: accessFlags(o) },
|
|
11785
|
+
file: false
|
|
11786
|
+
};
|
|
11709
11787
|
case "sealed":
|
|
11710
|
-
return { fd: yield { op: "fd-open-sealed" }, file: false };
|
|
11788
|
+
return { fd: yield { op: "fd-open-sealed", flags: accessFlags(o) }, file: false };
|
|
11711
11789
|
case "terminal": {
|
|
11712
11790
|
const req = node.pts === void 0 ? { op: "fd-open-tty", name: node.name } : { op: "pty-slave-open", n: node.pts, noctty: true };
|
|
11713
11791
|
return { fd: yield req, file: false };
|
|
@@ -12700,10 +12778,15 @@ function syncPathOps(kernel, resolve, statOf, open) {
|
|
|
12700
12778
|
if (inDev(abs)) return devSync(kernel, devReaddir(abs));
|
|
12701
12779
|
return kernel.json({ op: "readdir", path: abs });
|
|
12702
12780
|
},
|
|
12703
|
-
mkdir: (path) => void kernel.call({
|
|
12781
|
+
mkdir: (path, options) => void kernel.call({
|
|
12782
|
+
op: "mkdir",
|
|
12783
|
+
path: resolve(path),
|
|
12784
|
+
...options?.recursive === false ? { exclusive: true } : {}
|
|
12785
|
+
}),
|
|
12704
12786
|
rm: (path) => void kernel.call({ op: "rm", path: resolve(path) }),
|
|
12705
12787
|
unlink: (path) => void kernel.call({ op: "unlink", path: resolve(path) }),
|
|
12706
12788
|
rename: (from, to) => void kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
|
|
12789
|
+
chmod: (path, mode) => void kernel.call({ op: "chmod", path: resolve(path), mode: modeOf(mode) }),
|
|
12707
12790
|
link: (from, to) => void kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
|
|
12708
12791
|
symlink: (target, path) => void kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
|
|
12709
12792
|
readlink(path) {
|
|
@@ -13199,6 +13282,7 @@ function createContext(o) {
|
|
|
13199
13282
|
const sync = {
|
|
13200
13283
|
...syncOps(syncKernel, { pid: o.pid, resolve, random, infos, handles }),
|
|
13201
13284
|
run: (options) => runSync(syncKernel, { env: o.env, cwd: o.cwd, resolve, signal: signalNumber }, options),
|
|
13285
|
+
spawn: (options) => spawnSync(options),
|
|
13202
13286
|
exit: (status2 = 0) => {
|
|
13203
13287
|
exiting ??= status2 & 255;
|
|
13204
13288
|
return exitAtOnce(lane, [...writes], terminal.modes(), exiting);
|
|
@@ -13206,12 +13290,15 @@ function createContext(o) {
|
|
|
13206
13290
|
kill: killer({ self: o.pid, kernel, syncKernel, lane, writes, modes: terminal.modes }),
|
|
13207
13291
|
cred: () => syncKernel.json({ op: "proc-cred" }),
|
|
13208
13292
|
setcred(change) {
|
|
13209
|
-
if (typeof change !== "object" || change === null
|
|
13293
|
+
if (typeof change !== "object" || change === null || Array.isArray(change)) {
|
|
13294
|
+
throw new JsCallError("EINVAL", "setcred");
|
|
13295
|
+
}
|
|
13210
13296
|
return syncKernel.json({ op: "proc-setcred", change: { ...change } });
|
|
13211
13297
|
}
|
|
13212
13298
|
};
|
|
13213
13299
|
const io = { read: read2, send: writeAll, close: (fd) => ctx.close(fd) };
|
|
13214
|
-
const
|
|
13300
|
+
const defaults = { env: o.env, cwd: o.cwd, signal: signalNumber };
|
|
13301
|
+
const { spawnSync, ...children } = childOps(kernel, io, defaults, syncKernel);
|
|
13215
13302
|
const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
|
|
13216
13303
|
const ctx = {
|
|
13217
13304
|
argv: o.argv,
|
|
@@ -13402,10 +13489,15 @@ function pathOps(kernel, resolve, statOf, open) {
|
|
|
13402
13489
|
if (inDev(abs)) return devAsync(kernel, devReaddir(abs));
|
|
13403
13490
|
return await kernel.json({ op: "readdir", path: abs });
|
|
13404
13491
|
},
|
|
13405
|
-
mkdir: async (path) => void await kernel.call({
|
|
13492
|
+
mkdir: async (path, options) => void await kernel.call({
|
|
13493
|
+
op: "mkdir",
|
|
13494
|
+
path: resolve(path),
|
|
13495
|
+
...options?.recursive === false ? { exclusive: true } : {}
|
|
13496
|
+
}),
|
|
13406
13497
|
rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
|
|
13407
13498
|
unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
|
|
13408
13499
|
rename: async (from, to) => void await kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
|
|
13500
|
+
chmod: async (path, mode) => void await kernel.call({ op: "chmod", path: resolve(path), mode: modeOf(mode) }),
|
|
13409
13501
|
link: async (from, to) => void await kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
|
|
13410
13502
|
symlink: async (target, path) => void await kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
|
|
13411
13503
|
async readlink(path) {
|