@ai-ecoverse/slicc-kernel 1.73.3 → 1.75.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 +16 -2
- package/dist/index.js +56 -8
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +320 -32
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +198 -35
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +298 -43
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +198 -35
- package/dist/process-worker.js.map +3 -3
- package/package.json +2 -2
|
@@ -1343,7 +1343,7 @@ function promoteRequest(fd, f, handed) {
|
|
|
1343
1343
|
...f.buffer.handle !== void 0 ? { handle: f.buffer.handle } : {}
|
|
1344
1344
|
};
|
|
1345
1345
|
}
|
|
1346
|
-
var SYNTHETIC_DIRS, O_NONBLOCK, O_WRONLY, O_RDWR, O_APPEND, SEALED_PATH, WasiFds, GEN;
|
|
1346
|
+
var SYNTHETIC_DIRS, O_NONBLOCK, O_WRONLY, O_RDWR, O_APPEND, SEALED_PATH, CLIPBOARD_PATH, WasiFds, GEN;
|
|
1347
1347
|
var init_wasi_fds = __esm({
|
|
1348
1348
|
"src/process/wasi/wasi-fds.ts"() {
|
|
1349
1349
|
"use strict";
|
|
@@ -1357,6 +1357,7 @@ var init_wasi_fds = __esm({
|
|
|
1357
1357
|
O_RDWR = 2;
|
|
1358
1358
|
O_APPEND = 1024;
|
|
1359
1359
|
SEALED_PATH = "/dev/sealed";
|
|
1360
|
+
CLIPBOARD_PATH = "/dev/clipboard";
|
|
1360
1361
|
WasiFds = class {
|
|
1361
1362
|
table = /* @__PURE__ */ new Map();
|
|
1362
1363
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -1657,9 +1658,12 @@ var init_wasi_fds = __esm({
|
|
|
1657
1658
|
const e = this.get(fd);
|
|
1658
1659
|
this.table.delete(fd);
|
|
1659
1660
|
this.cloexec.delete(fd);
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1661
|
+
try {
|
|
1662
|
+
this.kernel.sys.close(fd);
|
|
1663
|
+
} finally {
|
|
1664
|
+
this.release(e);
|
|
1665
|
+
this.bump();
|
|
1666
|
+
}
|
|
1663
1667
|
}
|
|
1664
1668
|
renumber(from, to, keep = false) {
|
|
1665
1669
|
const e = this.get(from);
|
|
@@ -1822,8 +1826,8 @@ var init_wasi_fds = __esm({
|
|
|
1822
1826
|
const joined2 = path.startsWith("/") ? path : `${this.dir(dirfd).path}/${path}`;
|
|
1823
1827
|
return joined2.split("/").includes("..") ? physical(this.fs, joined2) : normalize(joined2);
|
|
1824
1828
|
}
|
|
1825
|
-
openKernelDevice(path, oflags, fdflags) {
|
|
1826
|
-
const { openSealed, openTty } = this.kernel.sys;
|
|
1829
|
+
openKernelDevice(path, oflags, fdflags, rights) {
|
|
1830
|
+
const { openSealed, openClipboard, openTty } = this.kernel.sys;
|
|
1827
1831
|
const nonblock = (fdflags & FDFLAGS.NONBLOCK) !== 0;
|
|
1828
1832
|
let fd;
|
|
1829
1833
|
let kind;
|
|
@@ -1832,6 +1836,9 @@ var init_wasi_fds = __esm({
|
|
|
1832
1836
|
if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
|
|
1833
1837
|
fd = openSealed.call(this.kernel.sys);
|
|
1834
1838
|
kind = "sealed";
|
|
1839
|
+
} else if (path === CLIPBOARD_PATH && openClipboard) {
|
|
1840
|
+
fd = this.openClipboard(openClipboard, oflags, rights);
|
|
1841
|
+
kind = "clipboard";
|
|
1835
1842
|
} else if (path === "/dev/tty" || /^\/dev\/tty\d+$/.test(path)) {
|
|
1836
1843
|
fd = openTty?.call(this.kernel.sys, path === "/dev/tty" ? void 0 : path);
|
|
1837
1844
|
if (fd === void 0) throw new WasiError("ENXIO");
|
|
@@ -1841,10 +1848,17 @@ var init_wasi_fds = __esm({
|
|
|
1841
1848
|
this.bump();
|
|
1842
1849
|
return fd;
|
|
1843
1850
|
}
|
|
1851
|
+
openClipboard(openClipboard, oflags, rights) {
|
|
1852
|
+
if (oflags & OFLAGS.DIRECTORY) throw new WasiError("ENOTDIR");
|
|
1853
|
+
if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
|
|
1854
|
+
const want = wantOf(oflags, rights);
|
|
1855
|
+
const flags = want === 6 ? O_RDWR : want === 2 ? O_WRONLY : 0;
|
|
1856
|
+
return openClipboard.call(this.kernel.sys, flags);
|
|
1857
|
+
}
|
|
1844
1858
|
open(path, oflags, rights, fdflags) {
|
|
1845
1859
|
const device2 = deviceOf(path);
|
|
1846
1860
|
if (device2) return this.install({ type: "device", device: device2 });
|
|
1847
|
-
const kernelDevice = this.openKernelDevice(path, oflags, fdflags);
|
|
1861
|
+
const kernelDevice = this.openKernelDevice(path, oflags, fdflags, rights);
|
|
1848
1862
|
if (kernelDevice !== void 0) return kernelDevice;
|
|
1849
1863
|
const alias = stdioAlias(path);
|
|
1850
1864
|
if (alias !== void 0) return this.reopen(alias);
|
|
@@ -2287,6 +2301,7 @@ function kernelFiletype(kind) {
|
|
|
2287
2301
|
switch (kind) {
|
|
2288
2302
|
case "tty":
|
|
2289
2303
|
case "sealed":
|
|
2304
|
+
case "clipboard":
|
|
2290
2305
|
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
|
|
2291
2306
|
case "device":
|
|
2292
2307
|
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
|
|
@@ -2444,7 +2459,7 @@ var init_wasi_host = __esm({
|
|
|
2444
2459
|
const e = fds.get(fd);
|
|
2445
2460
|
if (e.type === "device") return ROOT_IDS;
|
|
2446
2461
|
const kind = e.type === "kernel" ? fds.kind(fd, e) : "file";
|
|
2447
|
-
if (kind === "sealed") return ROOT_IDS;
|
|
2462
|
+
if (kind === "sealed" || kind === "clipboard") return ROOT_IDS;
|
|
2448
2463
|
if (kind !== "file") return void 0;
|
|
2449
2464
|
try {
|
|
2450
2465
|
return this.o.fs.stat(pathOf(fd));
|
|
@@ -2501,12 +2516,12 @@ var init_wasi_host = __esm({
|
|
|
2501
2516
|
fd_mode: (fd, out) => {
|
|
2502
2517
|
const e = fds.get(fd);
|
|
2503
2518
|
const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
|
|
2504
|
-
const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
|
|
2519
|
+
const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
|
|
2505
2520
|
mem.view().setUint32(out, mode, true);
|
|
2506
2521
|
},
|
|
2507
2522
|
path_mode: (dirfd, p, l, flags, out) => {
|
|
2508
2523
|
const path = at(dirfd, p, l);
|
|
2509
|
-
if (path ===
|
|
2524
|
+
if (this.synthetic(path) && deviceOf(path) === void 0)
|
|
2510
2525
|
return void mem.view().setUint32(out, SEALED_MODE, true);
|
|
2511
2526
|
const st = flags & AT_SYMLINK_NOFOLLOW ? this.o.fs.lstat(path) : this.o.fs.stat(path);
|
|
2512
2527
|
mem.view().setUint32(out, modeOf(st), true);
|
|
@@ -3009,7 +3024,7 @@ var init_wasi_host = __esm({
|
|
|
3009
3024
|
return gone ? { ...out, nlink: 0n } : out;
|
|
3010
3025
|
}
|
|
3011
3026
|
synthetic(path) {
|
|
3012
|
-
return deviceOf(path) !== void 0 || path === SEALED_PATH && !!this.o.kernel.sys.openSealed;
|
|
3027
|
+
return deviceOf(path) !== void 0 || path === SEALED_PATH && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH && !!this.o.kernel.sys.openClipboard;
|
|
3013
3028
|
}
|
|
3014
3029
|
pathFilestat(path, lookup2) {
|
|
3015
3030
|
if (this.synthetic(path)) {
|
|
@@ -3737,6 +3752,11 @@ var init_signals = __esm({
|
|
|
3737
3752
|
});
|
|
3738
3753
|
|
|
3739
3754
|
// src/process/js/js-kernel.ts
|
|
3755
|
+
function callError(result, op) {
|
|
3756
|
+
const { errno: errno2, message: message2 } = result;
|
|
3757
|
+
const detailed = typeof message2 === "string" && message2 !== errno2 && DETAILED.has(op);
|
|
3758
|
+
return new JsCallError(errno2, detailed ? `${op}: ${message2}` : op);
|
|
3759
|
+
}
|
|
3740
3760
|
function untilAborted(work, signal) {
|
|
3741
3761
|
if (!signal) return work;
|
|
3742
3762
|
return new Promise((resolve) => {
|
|
@@ -3753,7 +3773,7 @@ function caughtOf(handlers) {
|
|
|
3753
3773
|
for (const sig of handlers.keys()) caught |= sigbit(sig);
|
|
3754
3774
|
return caught;
|
|
3755
3775
|
}
|
|
3756
|
-
var JsCallError, JsKernel;
|
|
3776
|
+
var JsCallError, DETAILED, JsKernel;
|
|
3757
3777
|
var init_js_kernel = __esm({
|
|
3758
3778
|
"src/process/js/js-kernel.ts"() {
|
|
3759
3779
|
"use strict";
|
|
@@ -3768,6 +3788,12 @@ var init_js_kernel = __esm({
|
|
|
3768
3788
|
this.code = code2;
|
|
3769
3789
|
}
|
|
3770
3790
|
};
|
|
3791
|
+
DETAILED = /* @__PURE__ */ new Set([
|
|
3792
|
+
"fd-read",
|
|
3793
|
+
"fd-write",
|
|
3794
|
+
"fd-close",
|
|
3795
|
+
"fd-open-clipboard"
|
|
3796
|
+
]);
|
|
3771
3797
|
JsKernel = class {
|
|
3772
3798
|
header;
|
|
3773
3799
|
transport;
|
|
@@ -3794,7 +3820,7 @@ var init_js_kernel = __esm({
|
|
|
3794
3820
|
}
|
|
3795
3821
|
async call(req) {
|
|
3796
3822
|
const result = await this.raw(req);
|
|
3797
|
-
if (!result.ok) throw
|
|
3823
|
+
if (!result.ok) throw callError(result, req.op);
|
|
3798
3824
|
return result;
|
|
3799
3825
|
}
|
|
3800
3826
|
async json(req) {
|
|
@@ -3810,7 +3836,7 @@ var init_js_kernel = __esm({
|
|
|
3810
3836
|
const id = await this.submit(req, track);
|
|
3811
3837
|
const result = await this.settled(id, signal);
|
|
3812
3838
|
if (result.ok) return result;
|
|
3813
|
-
if (result.errno !== "EINTR") throw
|
|
3839
|
+
if (result.errno !== "EINTR") throw callError(result, req.op);
|
|
3814
3840
|
}
|
|
3815
3841
|
}
|
|
3816
3842
|
acks = [];
|
|
@@ -4002,6 +4028,7 @@ function childOps(kernel, io, defaults) {
|
|
|
4002
4028
|
const spawn = async (o) => {
|
|
4003
4029
|
const [file] = o.argv;
|
|
4004
4030
|
if (file === void 0) throw new JsCallError("EINVAL", "spawn");
|
|
4031
|
+
const group = groupOf(o, "spawn");
|
|
4005
4032
|
const mine = [];
|
|
4006
4033
|
const theirs = [];
|
|
4007
4034
|
try {
|
|
@@ -4012,7 +4039,8 @@ function childOps(kernel, io, defaults) {
|
|
|
4012
4039
|
argv: [...o.argv],
|
|
4013
4040
|
env: { ...o.env ?? defaults.env },
|
|
4014
4041
|
cwd: o.cwd ?? defaults.cwd,
|
|
4015
|
-
stdio
|
|
4042
|
+
stdio,
|
|
4043
|
+
...group
|
|
4016
4044
|
});
|
|
4017
4045
|
return childOf(pid, mine);
|
|
4018
4046
|
} catch (err) {
|
|
@@ -4024,6 +4052,15 @@ function childOps(kernel, io, defaults) {
|
|
|
4024
4052
|
};
|
|
4025
4053
|
return { spawn, wait: wait2, kill };
|
|
4026
4054
|
}
|
|
4055
|
+
function groupOf(o, call2) {
|
|
4056
|
+
const { pgid, session } = o;
|
|
4057
|
+
const valid = pgid === void 0 || Number.isInteger(pgid) && pgid >= 0;
|
|
4058
|
+
if (!valid || session !== void 0 && typeof session !== "boolean") {
|
|
4059
|
+
throw new JsCallError("EINVAL", call2);
|
|
4060
|
+
}
|
|
4061
|
+
if (session && pgid !== void 0) throw new JsCallError("EINVAL", call2);
|
|
4062
|
+
return session ? { session: true } : pgid !== void 0 ? { pgid } : {};
|
|
4063
|
+
}
|
|
4027
4064
|
async function closeAll(io, fds) {
|
|
4028
4065
|
for (const fd of fds) if (fd !== void 0) await io.close(fd).catch(() => void 0);
|
|
4029
4066
|
}
|
|
@@ -4179,6 +4216,7 @@ function* lookup(abs) {
|
|
|
4179
4216
|
const name2 = abs.slice("/dev/".length);
|
|
4180
4217
|
if (DEVICES.includes(name2)) return { kind: "device" };
|
|
4181
4218
|
if (name2 === "tty") return { kind: "tty" };
|
|
4219
|
+
if (name2 === "clipboard") return { kind: "clipboard" };
|
|
4182
4220
|
const std = STDIO3.indexOf(name2);
|
|
4183
4221
|
if (std >= 0) return { kind: "link", target: `${SELF_FD}/${std}`, fd: std };
|
|
4184
4222
|
if (name2 === "fd") return { kind: "link", target: SELF_FD };
|
|
@@ -4222,7 +4260,8 @@ function* fdStat(fd, path) {
|
|
|
4222
4260
|
return yield* pathStat(file.path);
|
|
4223
4261
|
}
|
|
4224
4262
|
if (info.terminal) return yield* terminalStat(info.terminal);
|
|
4225
|
-
if (info.kind === "device" || info.kind === "tty"
|
|
4263
|
+
if (info.kind === "device" || info.kind === "tty" || info.kind === "clipboard")
|
|
4264
|
+
return nodeStat(CHAR | 438);
|
|
4226
4265
|
if (info.kind === "socket") return nodeStat(49663);
|
|
4227
4266
|
return nodeStat(4480);
|
|
4228
4267
|
}
|
|
@@ -4232,6 +4271,7 @@ function* fdTarget(fd, path) {
|
|
|
4232
4271
|
if (info.kind === "file") return (yield { op: "fd-vfs-stat", fd }).path;
|
|
4233
4272
|
if (info.terminal) return info.terminal;
|
|
4234
4273
|
if (info.meta && "device" in info.meta) return `/dev/${info.meta.device}`;
|
|
4274
|
+
if (info.kind === "clipboard") return "/dev/clipboard";
|
|
4235
4275
|
return `${info.kind === "socket" ? "socket" : "pipe"}:[${fd}]`;
|
|
4236
4276
|
}
|
|
4237
4277
|
function linkStat(target) {
|
|
@@ -4244,6 +4284,7 @@ function* devStat(abs, follow2) {
|
|
|
4244
4284
|
return nodeStat(node.mode);
|
|
4245
4285
|
case "device":
|
|
4246
4286
|
case "tty":
|
|
4287
|
+
case "clipboard":
|
|
4247
4288
|
return nodeStat(CHAR | 438);
|
|
4248
4289
|
case "terminal":
|
|
4249
4290
|
return yield* terminalStat(node.name);
|
|
@@ -4278,7 +4319,7 @@ function* devReaddir(abs) {
|
|
|
4278
4319
|
if (node.kind !== "dir") throw new JsCallError("ENOTDIR", abs);
|
|
4279
4320
|
const names = yield { op: "fd-tty-names" };
|
|
4280
4321
|
const ttys = names.filter((n) => /^\/dev\/tty\d+$/.test(n)).map((n) => n.slice(5));
|
|
4281
|
-
return [...DEVICES, "tty", "fd", ...STDIO3, ...ttys].sort();
|
|
4322
|
+
return [...DEVICES, "clipboard", "tty", "fd", ...STDIO3, ...ttys].sort();
|
|
4282
4323
|
}
|
|
4283
4324
|
function* aliasOf(fd, abs, o) {
|
|
4284
4325
|
const info = yield* fdInfo(fd, abs);
|
|
@@ -4307,6 +4348,11 @@ function* opened(abs, o) {
|
|
|
4307
4348
|
return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
|
|
4308
4349
|
case "tty":
|
|
4309
4350
|
return { fd: yield { op: "fd-open-tty" }, file: false };
|
|
4351
|
+
case "clipboard": {
|
|
4352
|
+
const write2 = o.write === true || o.append === true || o.truncate === true;
|
|
4353
|
+
const flags = write2 ? o.read === true ? 2 : 1 : 0;
|
|
4354
|
+
return { fd: yield { op: "fd-open-clipboard", flags }, file: false };
|
|
4355
|
+
}
|
|
4310
4356
|
case "terminal": {
|
|
4311
4357
|
const req = node.pts === void 0 ? { op: "fd-open-tty", name: node.name } : { op: "pty-slave-open", n: node.pts, noctty: true };
|
|
4312
4358
|
return { fd: yield req, file: false };
|
|
@@ -5080,6 +5126,7 @@ function decodeRun(bytes, stdout, stderr) {
|
|
|
5080
5126
|
function runSync(kernel, d, o) {
|
|
5081
5127
|
const [file] = o.argv;
|
|
5082
5128
|
if (file === void 0) throw new JsCallError("EINVAL", "run");
|
|
5129
|
+
const group = groupOf(o, "run");
|
|
5083
5130
|
const stdout = stdioOf(o.stdout);
|
|
5084
5131
|
const stderr = stderrOf(o.stderr);
|
|
5085
5132
|
const input = typeof o.input === "string" ? encoder2.encode(o.input) : o.input;
|
|
@@ -5091,6 +5138,7 @@ function runSync(kernel, d, o) {
|
|
|
5091
5138
|
argv: [...o.argv],
|
|
5092
5139
|
env: { ...o.env ?? d.env },
|
|
5093
5140
|
cwd: o.cwd === void 0 ? d.cwd : d.resolve(o.cwd),
|
|
5141
|
+
...group,
|
|
5094
5142
|
stdin: stdioOf(o.stdin),
|
|
5095
5143
|
...input ? { input } : {},
|
|
5096
5144
|
stdout,
|
|
@@ -5106,6 +5154,7 @@ var encoder2, STDIO4;
|
|
|
5106
5154
|
var init_js_run = __esm({
|
|
5107
5155
|
"src/process/js/js-run.ts"() {
|
|
5108
5156
|
"use strict";
|
|
5157
|
+
init_js_children();
|
|
5109
5158
|
init_js_kernel();
|
|
5110
5159
|
encoder2 = new TextEncoder();
|
|
5111
5160
|
STDIO4 = /* @__PURE__ */ new Set(["pipe", "ignore", "inherit"]);
|
|
@@ -5604,7 +5653,7 @@ var init_js_sync = __esm({
|
|
|
5604
5653
|
}
|
|
5605
5654
|
call(req) {
|
|
5606
5655
|
const result = this.raw(req);
|
|
5607
|
-
if (!result.ok) throw
|
|
5656
|
+
if (!result.ok) throw callError(result, req.op);
|
|
5608
5657
|
return result;
|
|
5609
5658
|
}
|
|
5610
5659
|
json(req) {
|
|
@@ -5619,7 +5668,7 @@ var init_js_sync = __esm({
|
|
|
5619
5668
|
for (; ; ) {
|
|
5620
5669
|
const result = this.raw(req);
|
|
5621
5670
|
if (result.ok) return result;
|
|
5622
|
-
if (result.errno !== "EINTR") throw
|
|
5671
|
+
if (result.errno !== "EINTR") throw callError(result, req.op);
|
|
5623
5672
|
}
|
|
5624
5673
|
}
|
|
5625
5674
|
};
|
|
@@ -6211,7 +6260,7 @@ async function receiveSome(kernel, fd, max, signal) {
|
|
|
6211
6260
|
signal.throwIfAborted();
|
|
6212
6261
|
const r = await kernel.raw({ op: "fd-read", fd, max, nonblock: true });
|
|
6213
6262
|
if (r.ok) return r.kind === "bytes" ? r.bytes : new Uint8Array(0);
|
|
6214
|
-
if (r.errno !== "EAGAIN") throw
|
|
6263
|
+
if (r.errno !== "EAGAIN") throw callError(r, "fd-read");
|
|
6215
6264
|
await kernel.blocking({ op: "fd-select", read: [fd], write: [], timeoutMs: -1 }, signal);
|
|
6216
6265
|
}
|
|
6217
6266
|
}
|
|
@@ -6220,7 +6269,7 @@ async function sendSome(kernel, fd, body, signal) {
|
|
|
6220
6269
|
signal.throwIfAborted();
|
|
6221
6270
|
const r = await kernel.raw({ op: "fd-write", fd, body, nonblock: true });
|
|
6222
6271
|
if (r.ok) return written(r, body.length);
|
|
6223
|
-
if (r.errno !== "EAGAIN") throw
|
|
6272
|
+
if (r.errno !== "EAGAIN") throw callError(r, "fd-write");
|
|
6224
6273
|
await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
|
|
6225
6274
|
}
|
|
6226
6275
|
}
|
|
@@ -7394,7 +7443,7 @@ function ptyStat(path) {
|
|
|
7394
7443
|
ctime: now
|
|
7395
7444
|
};
|
|
7396
7445
|
}
|
|
7397
|
-
function sealedStat() {
|
|
7446
|
+
function sealedStat(minor = 250) {
|
|
7398
7447
|
const now = /* @__PURE__ */ new Date();
|
|
7399
7448
|
return {
|
|
7400
7449
|
dev: 22,
|
|
@@ -7403,7 +7452,7 @@ function sealedStat() {
|
|
|
7403
7452
|
nlink: 1,
|
|
7404
7453
|
uid: 0,
|
|
7405
7454
|
gid: 0,
|
|
7406
|
-
rdev: 10 << 8 |
|
|
7455
|
+
rdev: 10 << 8 | minor,
|
|
7407
7456
|
size: 0,
|
|
7408
7457
|
blksize: 4096,
|
|
7409
7458
|
blocks: 0,
|
|
@@ -7415,7 +7464,7 @@ function sealedStat() {
|
|
|
7415
7464
|
function nonblocking(stream) {
|
|
7416
7465
|
return (stream.flags & O_NONBLOCK2) !== 0 ? { nonblock: true } : void 0;
|
|
7417
7466
|
}
|
|
7418
|
-
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK2, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, SEALED_PATH2, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC2, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
7467
|
+
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK2, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, SEALED_PATH2, STRERROR, CLIPBOARD_PATH2, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC2, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
7419
7468
|
var init_kernel_streams = __esm({
|
|
7420
7469
|
"src/process/kernel-streams.ts"() {
|
|
7421
7470
|
"use strict";
|
|
@@ -7433,6 +7482,16 @@ var init_kernel_streams = __esm({
|
|
|
7433
7482
|
TTY_PATH = /^\/dev\/tty\d+$/;
|
|
7434
7483
|
TTY_NAME = /^tty\d+$/;
|
|
7435
7484
|
SEALED_PATH2 = "/dev/sealed";
|
|
7485
|
+
STRERROR = {
|
|
7486
|
+
EACCES: "Permission denied",
|
|
7487
|
+
EIO: "I/O error",
|
|
7488
|
+
ENOTSUP: "Not supported",
|
|
7489
|
+
EOPNOTSUPP: "Not supported",
|
|
7490
|
+
EFBIG: "File too large",
|
|
7491
|
+
EILSEQ: "Illegal byte sequence",
|
|
7492
|
+
EINTR: "Interrupted system call"
|
|
7493
|
+
};
|
|
7494
|
+
CLIPBOARD_PATH2 = "/dev/clipboard";
|
|
7436
7495
|
O_CREAT = 64;
|
|
7437
7496
|
O_EXCL = 128;
|
|
7438
7497
|
O_NOCTTY = 256;
|
|
@@ -7508,10 +7567,64 @@ var init_kernel_streams = __esm({
|
|
|
7508
7567
|
}
|
|
7509
7568
|
listSealed() {
|
|
7510
7569
|
const { analyzePath, mkdev, makedev } = this.Fs;
|
|
7511
|
-
if (!
|
|
7512
|
-
|
|
7570
|
+
if (!analyzePath || !mkdev || !makedev) return;
|
|
7571
|
+
const nodes = [
|
|
7572
|
+
[SEALED_PATH2, 250, this.sys.openSealed],
|
|
7573
|
+
[CLIPBOARD_PATH2, 251, this.sys.openClipboard]
|
|
7574
|
+
];
|
|
7575
|
+
for (const [path, minor, present] of nodes) {
|
|
7576
|
+
if (!present || analyzePath.call(this.Fs, path).exists) continue;
|
|
7577
|
+
try {
|
|
7578
|
+
mkdev.call(this.Fs, path, makedev.call(this.Fs, 10, minor));
|
|
7579
|
+
} catch {
|
|
7580
|
+
}
|
|
7581
|
+
}
|
|
7582
|
+
}
|
|
7583
|
+
reporting = /* @__PURE__ */ new Set();
|
|
7584
|
+
reportClose(kfd) {
|
|
7585
|
+
this.reporting.add(kfd);
|
|
7586
|
+
}
|
|
7587
|
+
quitting = false;
|
|
7588
|
+
atExit = false;
|
|
7589
|
+
failedAtExit = false;
|
|
7590
|
+
committed = /* @__PURE__ */ new Set();
|
|
7591
|
+
exiting() {
|
|
7592
|
+
this.atExit = true;
|
|
7593
|
+
return () => {
|
|
7594
|
+
this.atExit = false;
|
|
7595
|
+
};
|
|
7596
|
+
}
|
|
7597
|
+
commitStdout() {
|
|
7598
|
+
const kfd = this.Fs.getStream(1)?.sliccKernelFd;
|
|
7599
|
+
if (kfd === void 0 || !this.reporting.delete(kfd)) return;
|
|
7600
|
+
this.committed.add(kfd);
|
|
7513
7601
|
try {
|
|
7514
|
-
|
|
7602
|
+
this.sys.close(kfd);
|
|
7603
|
+
} catch (e) {
|
|
7604
|
+
if (e instanceof SyscallError) this.stdoutFailed(e.code);
|
|
7605
|
+
}
|
|
7606
|
+
}
|
|
7607
|
+
exitStatus(status2) {
|
|
7608
|
+
return this.failedAtExit && status2 === 0 ? 1 : status2;
|
|
7609
|
+
}
|
|
7610
|
+
reportedClose(stream, kfd) {
|
|
7611
|
+
try {
|
|
7612
|
+
this.sys.close(kfd);
|
|
7613
|
+
} catch (e) {
|
|
7614
|
+
if (this.quitting && stream.fd === 1 && e instanceof SyscallError) this.stdoutFailed(e.code);
|
|
7615
|
+
this.call(() => {
|
|
7616
|
+
throw e;
|
|
7617
|
+
});
|
|
7618
|
+
}
|
|
7619
|
+
}
|
|
7620
|
+
stdoutFailed(code2) {
|
|
7621
|
+
this.failedAtExit = true;
|
|
7622
|
+
const stderr = this.Fs.getStream(2)?.sliccKernelFd;
|
|
7623
|
+
if (stderr === void 0) return;
|
|
7624
|
+
const line = `${this.options.program ?? "program"}: write error: ${STRERROR[code2] ?? code2}
|
|
7625
|
+
`;
|
|
7626
|
+
try {
|
|
7627
|
+
this.sys.write(stderr, new TextEncoder().encode(line));
|
|
7515
7628
|
} catch {
|
|
7516
7629
|
}
|
|
7517
7630
|
}
|
|
@@ -7614,7 +7727,7 @@ var init_kernel_streams = __esm({
|
|
|
7614
7727
|
if (device2 !== void 0 && TTY_PATH.test(device2) && !this.terminalExists(device2)) {
|
|
7615
7728
|
throw new this.Fs.ErrnoError(wasiErrno("ENOENT"));
|
|
7616
7729
|
}
|
|
7617
|
-
const pty = this.openPty(open, path, flags, mode) ?? this.openSealed(open, path, flags, mode);
|
|
7730
|
+
const pty = this.openPty(open, path, flags, mode) ?? this.openSealed(open, path, flags, mode) ?? this.openClipboard(open, path, flags, mode);
|
|
7618
7731
|
if (pty) return pty;
|
|
7619
7732
|
this.refuseExclusiveLink(path, flags);
|
|
7620
7733
|
const stream = this.openRacing(open, path, flags, mode);
|
|
@@ -7680,6 +7793,14 @@ var init_kernel_streams = __esm({
|
|
|
7680
7793
|
const kfd = this.call(() => openSealed.call(this.sys));
|
|
7681
7794
|
return this.vessel(open, kfd, { path, flags, mode }, false);
|
|
7682
7795
|
}
|
|
7796
|
+
openClipboard(open, path, flags, mode) {
|
|
7797
|
+
const { openClipboard } = this.sys;
|
|
7798
|
+
if (path !== CLIPBOARD_PATH2 || !openClipboard) return void 0;
|
|
7799
|
+
const kfd = this.call(() => openClipboard.call(this.sys, flags & 3));
|
|
7800
|
+
const stream = this.vessel(open, kfd, { path, flags, mode }, false);
|
|
7801
|
+
this.reportClose(kfd);
|
|
7802
|
+
return stream;
|
|
7803
|
+
}
|
|
7683
7804
|
vessel(open, kfd, at, terminal) {
|
|
7684
7805
|
let stream;
|
|
7685
7806
|
try {
|
|
@@ -7704,6 +7825,7 @@ var init_kernel_streams = __esm({
|
|
|
7704
7825
|
if (typeof original !== "function") continue;
|
|
7705
7826
|
fs[name2] = (path, ...rest2) => {
|
|
7706
7827
|
if (path === SEALED_PATH2 && this.sys.openSealed) return sealedStat();
|
|
7828
|
+
if (path === CLIPBOARD_PATH2 && this.sys.openClipboard) return sealedStat(251);
|
|
7707
7829
|
const owned = this.ownedTty(path);
|
|
7708
7830
|
if (owned && isPtyPath(path)) return this.owned(path, ptyStat(path));
|
|
7709
7831
|
if (!isPtyPath(path)) {
|
|
@@ -7844,6 +7966,7 @@ var init_kernel_streams = __esm({
|
|
|
7844
7966
|
this.refs.set(kfd, (this.refs.get(kfd) ?? 0) + 1);
|
|
7845
7967
|
},
|
|
7846
7968
|
close: (stream) => {
|
|
7969
|
+
if (this.atExit && stream.fd === 2 && this.reporting.size > 0) this.commitStdout();
|
|
7847
7970
|
try {
|
|
7848
7971
|
base.close?.(stream);
|
|
7849
7972
|
} catch {
|
|
@@ -7854,6 +7977,11 @@ var init_kernel_streams = __esm({
|
|
|
7854
7977
|
return;
|
|
7855
7978
|
}
|
|
7856
7979
|
this.refs.delete(kfd);
|
|
7980
|
+
if (this.committed.size > 0 && this.committed.delete(kfd)) return;
|
|
7981
|
+
if (this.reporting.size > 0 && this.reporting.delete(kfd)) {
|
|
7982
|
+
this.reportedClose(stream, kfd);
|
|
7983
|
+
return;
|
|
7984
|
+
}
|
|
7857
7985
|
try {
|
|
7858
7986
|
this.sys.close(kfd);
|
|
7859
7987
|
} catch {
|
|
@@ -8701,7 +8829,7 @@ function place(Fs, stream, fd) {
|
|
|
8701
8829
|
function placeholder(Fs, streams, entry) {
|
|
8702
8830
|
if (entry.kind === "socket") return streams.socketStream(entry.flags ?? O_RDWR4);
|
|
8703
8831
|
if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR4);
|
|
8704
|
-
if (entry.kind === "stream") return Fs.open("/dev/null", O_RDWR4);
|
|
8832
|
+
if (entry.kind === "stream" || entry.kind === "clipboard") return Fs.open("/dev/null", O_RDWR4);
|
|
8705
8833
|
Fs.mkdirTree(PLACEHOLDER_DIR);
|
|
8706
8834
|
return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`, O_RDWR4 | O_CREAT3);
|
|
8707
8835
|
}
|
|
@@ -8725,6 +8853,7 @@ function placeKernelStream(Fs, streams, entry) {
|
|
|
8725
8853
|
streams.sizeFromKernel(stream, entry.kernel);
|
|
8726
8854
|
} else if (entry.kind === "socket") streams.attachSocket(stream, entry.kernel);
|
|
8727
8855
|
else streams.attach(stream, entry.kernel, entry.kind === "tty");
|
|
8856
|
+
if (entry.kind === "clipboard") streams.reportClose(entry.kernel);
|
|
8728
8857
|
if (entry.kind === "tty") streams.nameTerminal(stream);
|
|
8729
8858
|
if (entry.kind === "stream") {
|
|
8730
8859
|
asFifo(stream, streams, entry.desc !== void 0 ? `d${entry.desc}` : `k${entry.kernel}`);
|
|
@@ -9865,6 +9994,9 @@ function kernelSys(transport) {
|
|
|
9865
9994
|
openSealed() {
|
|
9866
9995
|
return json2(call2({ op: "fd-open-sealed" }, "fd-open-sealed"));
|
|
9867
9996
|
},
|
|
9997
|
+
openClipboard(flags) {
|
|
9998
|
+
return json2(call2({ op: "fd-open-clipboard", flags }, "fd-open-clipboard"));
|
|
9999
|
+
},
|
|
9868
10000
|
ptyNumbers() {
|
|
9869
10001
|
return json2(call2({ op: "pty-list" }, "pty-list"));
|
|
9870
10002
|
},
|
|
@@ -10021,6 +10153,8 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
10021
10153
|
let failed5;
|
|
10022
10154
|
let memory;
|
|
10023
10155
|
let exports;
|
|
10156
|
+
let atExit = () => () => {
|
|
10157
|
+
};
|
|
10024
10158
|
const initialized = new Promise((resolve, reject) => {
|
|
10025
10159
|
ready = resolve;
|
|
10026
10160
|
failed5 = reject;
|
|
@@ -10062,7 +10196,10 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
10062
10196
|
memory = wasmMemory(instance, imports);
|
|
10063
10197
|
exports = instance.exports;
|
|
10064
10198
|
publishMemory(init.sab, memory?.buffer.byteLength ?? 0);
|
|
10065
|
-
done(
|
|
10199
|
+
done(
|
|
10200
|
+
withExitHook(instance, () => atExit()),
|
|
10201
|
+
init.program.module
|
|
10202
|
+
);
|
|
10066
10203
|
}, failed5);
|
|
10067
10204
|
return {};
|
|
10068
10205
|
},
|
|
@@ -10095,9 +10232,17 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
10095
10232
|
const sigpipe = () => running.sliccSigpipe?.() === 1;
|
|
10096
10233
|
const restartable = () => signals.restartable();
|
|
10097
10234
|
const owners = init.owners ? { owners: true } : {};
|
|
10098
|
-
const streams = new KernelStreams(running.FS, sys, {
|
|
10235
|
+
const streams = new KernelStreams(running.FS, sys, {
|
|
10236
|
+
sigpipe,
|
|
10237
|
+
restartable,
|
|
10238
|
+
...owners,
|
|
10239
|
+
program: init.argv0
|
|
10240
|
+
});
|
|
10099
10241
|
trackCloseOnExec(running.FS);
|
|
10100
|
-
quietQuit(running.FS)
|
|
10242
|
+
quietQuit(running.FS, (on) => {
|
|
10243
|
+
streams.quitting = on;
|
|
10244
|
+
});
|
|
10245
|
+
atExit = () => streams.exiting();
|
|
10101
10246
|
useMounts(running.FS, init.env, true);
|
|
10102
10247
|
useZeroDevices(running.FS);
|
|
10103
10248
|
useProcfs(running.FS, sys, init.pid);
|
|
@@ -10143,7 +10288,7 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
10143
10288
|
restartable
|
|
10144
10289
|
});
|
|
10145
10290
|
try {
|
|
10146
|
-
return runMain(running, init);
|
|
10291
|
+
return streams.exitStatus(runMain(running, init));
|
|
10147
10292
|
} finally {
|
|
10148
10293
|
try {
|
|
10149
10294
|
vfs.flush();
|
|
@@ -10151,10 +10296,27 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
10151
10296
|
}
|
|
10152
10297
|
}
|
|
10153
10298
|
}
|
|
10154
|
-
function
|
|
10299
|
+
function withExitHook(instance, begin) {
|
|
10300
|
+
const funcs = instance.exports.__funcs_on_exit;
|
|
10301
|
+
if (typeof funcs !== "function") return instance;
|
|
10302
|
+
const run = funcs;
|
|
10303
|
+
const exported = Object.assign(/* @__PURE__ */ Object.create(null), instance.exports, {
|
|
10304
|
+
__funcs_on_exit: () => {
|
|
10305
|
+
const end = begin();
|
|
10306
|
+
try {
|
|
10307
|
+
run();
|
|
10308
|
+
} finally {
|
|
10309
|
+
end();
|
|
10310
|
+
}
|
|
10311
|
+
}
|
|
10312
|
+
});
|
|
10313
|
+
return { exports: exported };
|
|
10314
|
+
}
|
|
10315
|
+
function quietQuit(Fs, quitting) {
|
|
10155
10316
|
const { quit, close } = Fs;
|
|
10156
10317
|
if (!quit) return;
|
|
10157
10318
|
Fs.quit = () => {
|
|
10319
|
+
quitting?.(true);
|
|
10158
10320
|
Fs.close = (stream) => {
|
|
10159
10321
|
try {
|
|
10160
10322
|
close.call(Fs, stream);
|
|
@@ -10164,6 +10326,7 @@ function quietQuit(Fs) {
|
|
|
10164
10326
|
try {
|
|
10165
10327
|
quit.call(Fs);
|
|
10166
10328
|
} finally {
|
|
10329
|
+
quitting?.(false);
|
|
10167
10330
|
Fs.close = close;
|
|
10168
10331
|
}
|
|
10169
10332
|
};
|
|
@@ -10216,7 +10379,7 @@ var init_process_runtime = __esm({
|
|
|
10216
10379
|
O_ACCMODE4 = 3;
|
|
10217
10380
|
O_DIRECTORY = 65536;
|
|
10218
10381
|
accessMode = (access) => access === "read" ? O_RDONLY : access === "write" ? O_WRONLY6 : O_RDWR6;
|
|
10219
|
-
PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket"]);
|
|
10382
|
+
PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket", "clipboard"]);
|
|
10220
10383
|
GLUE_TRAILER = [
|
|
10221
10384
|
"if (typeof ENV !== 'undefined') Object.assign(ENV, Module.sliccEnv);",
|
|
10222
10385
|
"const __sliccTake = (name, value) => {",
|