@ai-ecoverse/slicc-kernel 1.34.0 → 1.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/dist/kernel-worker.js +124 -45
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +246 -19
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +129 -49
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +246 -19
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/dist/process-worker.js
CHANGED
|
@@ -594,6 +594,26 @@ function toMs(v) {
|
|
|
594
594
|
}
|
|
595
595
|
function createHelpers(Fs, ops) {
|
|
596
596
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
597
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
598
|
+
function markDirty(node) {
|
|
599
|
+
node.live.dirty = true;
|
|
600
|
+
dirty.add(node);
|
|
601
|
+
}
|
|
602
|
+
function flushDirty() {
|
|
603
|
+
for (const node of [...dirty]) {
|
|
604
|
+
const s = node.live;
|
|
605
|
+
if (!s.dirty || s.orphan) {
|
|
606
|
+
dirty.delete(node);
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
if (!s.ranged && s.len > EARLY_WHOLE_FILE) continue;
|
|
610
|
+
try {
|
|
611
|
+
flushNode(node);
|
|
612
|
+
dirty.delete(node);
|
|
613
|
+
} catch {
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
597
617
|
function call2(fn) {
|
|
598
618
|
try {
|
|
599
619
|
return fn();
|
|
@@ -688,7 +708,7 @@ function createHelpers(Fs, ops) {
|
|
|
688
708
|
const ranged = s.openCount > 0 ? rangedOf(node) : void 0;
|
|
689
709
|
if (ranged) {
|
|
690
710
|
ranged.truncate(size);
|
|
691
|
-
|
|
711
|
+
markDirty(node);
|
|
692
712
|
return;
|
|
693
713
|
}
|
|
694
714
|
if (s.openCount > 0) {
|
|
@@ -697,7 +717,7 @@ function createHelpers(Fs, ops) {
|
|
|
697
717
|
const buf = ensureCapacity(node, size);
|
|
698
718
|
if (size > s.len) buf.fill(0, s.len, size);
|
|
699
719
|
s.len = size;
|
|
700
|
-
|
|
720
|
+
markDirty(node);
|
|
701
721
|
return;
|
|
702
722
|
}
|
|
703
723
|
const path = liveNodePath(node);
|
|
@@ -727,6 +747,8 @@ function createHelpers(Fs, ops) {
|
|
|
727
747
|
ensureCapacity,
|
|
728
748
|
rangedOf,
|
|
729
749
|
flushNode,
|
|
750
|
+
markDirty,
|
|
751
|
+
flushDirty,
|
|
730
752
|
truncate
|
|
731
753
|
};
|
|
732
754
|
}
|
|
@@ -971,7 +993,7 @@ function createStreamOps(h) {
|
|
|
971
993
|
if (ranged) {
|
|
972
994
|
const bytes = new Uint8Array(buffer.buffer, buffer.byteOffset + offset, length);
|
|
973
995
|
h.call(() => ranged.write(position, bytes));
|
|
974
|
-
|
|
996
|
+
h.markDirty(node);
|
|
975
997
|
return length;
|
|
976
998
|
}
|
|
977
999
|
ensureLoaded(node);
|
|
@@ -979,7 +1001,7 @@ function createStreamOps(h) {
|
|
|
979
1001
|
if (position > s.len) buf.fill(0, s.len, position);
|
|
980
1002
|
buf.set(new Uint8Array(buffer.buffer, buffer.byteOffset + offset, length), position);
|
|
981
1003
|
s.len = Math.max(s.len, end);
|
|
982
|
-
|
|
1004
|
+
h.markDirty(node);
|
|
983
1005
|
return length;
|
|
984
1006
|
},
|
|
985
1007
|
llseek(stream, offset, whence) {
|
|
@@ -1009,6 +1031,7 @@ function createLiveVfsPlugin(Fs) {
|
|
|
1009
1031
|
mounts,
|
|
1010
1032
|
node_ops: nodeOps,
|
|
1011
1033
|
stream_ops: streamOps,
|
|
1034
|
+
flushDirty: () => h.flushDirty(),
|
|
1012
1035
|
mount(mount) {
|
|
1013
1036
|
const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
|
|
1014
1037
|
if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
|
|
@@ -1173,7 +1196,7 @@ function guardRenames(Fs) {
|
|
|
1173
1196
|
rename(from, to);
|
|
1174
1197
|
};
|
|
1175
1198
|
}
|
|
1176
|
-
var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END;
|
|
1199
|
+
var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE;
|
|
1177
1200
|
var init_live_vfs_fs = __esm({
|
|
1178
1201
|
"src/realm/live-vfs-fs.ts"() {
|
|
1179
1202
|
"use strict";
|
|
@@ -1188,6 +1211,7 @@ var init_live_vfs_fs = __esm({
|
|
|
1188
1211
|
UMASK = 18;
|
|
1189
1212
|
SEEK_CUR = 1;
|
|
1190
1213
|
SEEK_END = 2;
|
|
1214
|
+
EARLY_WHOLE_FILE = 64 * 1024;
|
|
1191
1215
|
}
|
|
1192
1216
|
});
|
|
1193
1217
|
|
|
@@ -1224,6 +1248,7 @@ function mountVfsIntoEmscripten(Fs, deps) {
|
|
|
1224
1248
|
return {
|
|
1225
1249
|
mounted,
|
|
1226
1250
|
flush: () => flushLiveVfs(Fs, plugin),
|
|
1251
|
+
flushDirty: () => plugin.flushDirty(),
|
|
1227
1252
|
invalidate: () => invalidateLiveVfs(Fs, plugin)
|
|
1228
1253
|
};
|
|
1229
1254
|
}
|
|
@@ -1268,10 +1293,34 @@ function parseSyncFsStat(json) {
|
|
|
1268
1293
|
...typeof s.version === "string" ? { version: s.version } : {}
|
|
1269
1294
|
};
|
|
1270
1295
|
}
|
|
1271
|
-
var SYNC_FS_REQUEST_TIMEOUT_MS;
|
|
1296
|
+
var SYNC_FS_OPS, SYNC_FS_REQUEST_TIMEOUT_MS;
|
|
1272
1297
|
var init_sync_fs_wire = __esm({
|
|
1273
1298
|
"src/realm/sync-fs-wire.ts"() {
|
|
1274
1299
|
"use strict";
|
|
1300
|
+
SYNC_FS_OPS = [
|
|
1301
|
+
"read",
|
|
1302
|
+
"write",
|
|
1303
|
+
"exists",
|
|
1304
|
+
"stat",
|
|
1305
|
+
"lstat",
|
|
1306
|
+
"readdir",
|
|
1307
|
+
"readdir-stat",
|
|
1308
|
+
"mkdir",
|
|
1309
|
+
"rm",
|
|
1310
|
+
"rename",
|
|
1311
|
+
"unlink",
|
|
1312
|
+
"rmdir",
|
|
1313
|
+
"symlink",
|
|
1314
|
+
"readlink",
|
|
1315
|
+
"chmod",
|
|
1316
|
+
"utimes",
|
|
1317
|
+
"lutimes",
|
|
1318
|
+
"statfs",
|
|
1319
|
+
"hold",
|
|
1320
|
+
"pread",
|
|
1321
|
+
"pwrite",
|
|
1322
|
+
"truncate"
|
|
1323
|
+
];
|
|
1275
1324
|
SYNC_FS_REQUEST_TIMEOUT_MS = 25e3;
|
|
1276
1325
|
}
|
|
1277
1326
|
});
|
|
@@ -1558,7 +1607,7 @@ function ptyStat(path) {
|
|
|
1558
1607
|
function nonblocking(stream) {
|
|
1559
1608
|
return (stream.flags & O_NONBLOCK) !== 0 ? { nonblock: true } : void 0;
|
|
1560
1609
|
}
|
|
1561
|
-
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
1610
|
+
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
1562
1611
|
var init_kernel_streams = __esm({
|
|
1563
1612
|
"src/process/kernel-streams.ts"() {
|
|
1564
1613
|
"use strict";
|
|
@@ -1573,6 +1622,7 @@ var init_kernel_streams = __esm({
|
|
|
1573
1622
|
SOCKET_MODE = 49663;
|
|
1574
1623
|
PTY_PATH = /^\/dev\/(?:ptmx|pts\/(\d+))$/;
|
|
1575
1624
|
TTY_PATH = /^\/dev\/tty\d+$/;
|
|
1625
|
+
TTY_NAME = /^tty\d+$/;
|
|
1576
1626
|
O_CREAT = 64;
|
|
1577
1627
|
O_EXCL = 128;
|
|
1578
1628
|
O_NOCTTY = 256;
|
|
@@ -1646,6 +1696,36 @@ var init_kernel_streams = __esm({
|
|
|
1646
1696
|
if (typeof this.Fs.stat !== "function") return;
|
|
1647
1697
|
stream.stream_ops = { ...stream.stream_ops, getattr: () => this.Fs.stat?.(name) ?? {} };
|
|
1648
1698
|
}
|
|
1699
|
+
creatingTerminal = false;
|
|
1700
|
+
useTerminalNodes() {
|
|
1701
|
+
const fs = this.Fs;
|
|
1702
|
+
const { lookupNode, readdir, getPath, mkdev, makedev } = fs;
|
|
1703
|
+
const ttyNames = this.sys.ttyNames?.bind(this.sys);
|
|
1704
|
+
if (!lookupNode || !readdir || !getPath || !mkdev || !makedev || !ttyNames) return;
|
|
1705
|
+
fs.lookupNode = (parent, name) => {
|
|
1706
|
+
try {
|
|
1707
|
+
return lookupNode.call(fs, parent, name);
|
|
1708
|
+
} catch (e) {
|
|
1709
|
+
const path = `/dev/${name}`;
|
|
1710
|
+
if (this.creatingTerminal || !TTY_NAME.test(name) || getPath.call(fs, parent) !== "/dev")
|
|
1711
|
+
throw e;
|
|
1712
|
+
if (!ttyNames().includes(path)) throw e;
|
|
1713
|
+
this.creatingTerminal = true;
|
|
1714
|
+
try {
|
|
1715
|
+
mkdev.call(fs, path, makedev.call(fs, 6, 0));
|
|
1716
|
+
} finally {
|
|
1717
|
+
this.creatingTerminal = false;
|
|
1718
|
+
}
|
|
1719
|
+
return lookupNode.call(fs, parent, name);
|
|
1720
|
+
}
|
|
1721
|
+
};
|
|
1722
|
+
fs.readdir = (path) => {
|
|
1723
|
+
const names = readdir.call(fs, path);
|
|
1724
|
+
if (path.replace(/\/+$/, "") !== "/dev") return names;
|
|
1725
|
+
const missing = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name) => TTY_NAME.test(name) && !names.includes(name));
|
|
1726
|
+
return [...names, ...missing];
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1649
1729
|
ttyNode(name) {
|
|
1650
1730
|
const { analyzePath, mkdev, makedev } = this.Fs;
|
|
1651
1731
|
if (!TTY_PATH.test(name) || !analyzePath || !mkdev || !makedev) return;
|
|
@@ -1707,8 +1787,13 @@ var init_kernel_streams = __esm({
|
|
|
1707
1787
|
useControllingTerminal() {
|
|
1708
1788
|
if (typeof this.Fs.open !== "function") return;
|
|
1709
1789
|
this.usePtyPaths();
|
|
1790
|
+
this.useTerminalNodes();
|
|
1710
1791
|
const open = this.Fs.open.bind(this.Fs);
|
|
1711
1792
|
this.Fs.open = (path, flags, mode) => {
|
|
1793
|
+
const device = typeof path === "string" ? this.devicePath(path) : void 0;
|
|
1794
|
+
if (device !== void 0 && TTY_PATH.test(device) && !this.terminalExists(device)) {
|
|
1795
|
+
throw new this.Fs.ErrnoError(wasiErrno("ENOENT"));
|
|
1796
|
+
}
|
|
1712
1797
|
const pty = this.openPty(open, path, flags, mode);
|
|
1713
1798
|
if (pty) return pty;
|
|
1714
1799
|
const stream = open(path, flags, mode);
|
|
@@ -1781,6 +1866,23 @@ var init_kernel_streams = __esm({
|
|
|
1781
1866
|
const exists = n === void 0 ? this.sys.openPty !== void 0 : this.sys.ptyNumbers?.().includes(Number(n)) ?? false;
|
|
1782
1867
|
if (!exists) throw new this.Fs.ErrnoError(wasiErrno("ENOENT"));
|
|
1783
1868
|
}
|
|
1869
|
+
devicePath(path) {
|
|
1870
|
+
const name = path.slice(path.lastIndexOf("/") + 1);
|
|
1871
|
+
if (!TTY_NAME.test(name)) return void 0;
|
|
1872
|
+
const { lookupPath, cwd } = this.Fs;
|
|
1873
|
+
const absolute = path.startsWith("/") ? path : `${cwd?.call(this.Fs) ?? "/"}/${path}`;
|
|
1874
|
+
const dir = absolute.slice(0, absolute.lastIndexOf("/")) || "/";
|
|
1875
|
+
try {
|
|
1876
|
+
const real = lookupPath?.call(this.Fs, dir, { follow: true }).path ?? dir;
|
|
1877
|
+
return `${real === "/" ? "" : real}/${name}`;
|
|
1878
|
+
} catch {
|
|
1879
|
+
return absolute;
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
terminalExists(path) {
|
|
1883
|
+
const { analyzePath } = this.Fs;
|
|
1884
|
+
return analyzePath?.call(this.Fs, path).exists ?? true;
|
|
1885
|
+
}
|
|
1784
1886
|
openNamedTerminal(path) {
|
|
1785
1887
|
const { openTty } = this.sys;
|
|
1786
1888
|
if (!openTty) return void 0;
|
|
@@ -2095,6 +2197,37 @@ function pathOpensLinks(Fs) {
|
|
|
2095
2197
|
if (!mayOpen || !isLink) return;
|
|
2096
2198
|
fs.mayOpen = (node, flags) => flags & O_PATH && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
|
|
2097
2199
|
}
|
|
2200
|
+
function kernelUmask(imports, deps) {
|
|
2201
|
+
let umask = deps.initial & 511;
|
|
2202
|
+
for (const ns of namespaces(imports)) {
|
|
2203
|
+
const { __syscall_openat: openat, __syscall_mkdirat: mkdirat } = ns;
|
|
2204
|
+
const { __syscall_mknodat: mknodat, __syscall_umask: own } = ns;
|
|
2205
|
+
if (typeof openat === "function") {
|
|
2206
|
+
ns.__syscall_openat = (dirfd, path, flags, varargs) => {
|
|
2207
|
+
const memory = deps.memory();
|
|
2208
|
+
if (flags & O_CREAT2 && varargs && memory)
|
|
2209
|
+
new Int32Array(memory.buffer)[varargs >> 2] &= ~umask;
|
|
2210
|
+
return openat(dirfd, path, flags, varargs);
|
|
2211
|
+
};
|
|
2212
|
+
}
|
|
2213
|
+
if (typeof mkdirat === "function") {
|
|
2214
|
+
ns.__syscall_mkdirat = (dirfd, path, mode) => mkdirat(dirfd, path, mode & ~umask);
|
|
2215
|
+
}
|
|
2216
|
+
if (typeof mknodat === "function") {
|
|
2217
|
+
ns.__syscall_mknodat = (dirfd, path, mode, dev) => mknodat(dirfd, path, mode & ~umask, dev);
|
|
2218
|
+
}
|
|
2219
|
+
if (typeof own === "function") {
|
|
2220
|
+
own(umask);
|
|
2221
|
+
ns.__syscall_umask = (mask) => {
|
|
2222
|
+
const old = umask;
|
|
2223
|
+
umask = mask & 511;
|
|
2224
|
+
own(umask);
|
|
2225
|
+
deps.set(umask);
|
|
2226
|
+
return old;
|
|
2227
|
+
};
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2098
2231
|
function noFollowUtimes(imports, fs, glue) {
|
|
2099
2232
|
for (const namespace of namespaces(imports)) {
|
|
2100
2233
|
const key = Object.keys(namespace).find(
|
|
@@ -2760,7 +2893,6 @@ function createProcessKernel(deps) {
|
|
|
2760
2893
|
if (!stream) return { none: true };
|
|
2761
2894
|
promote?.(stream);
|
|
2762
2895
|
if (stream.sliccKernelFd !== void 0) return { fd: stream.sliccKernelFd };
|
|
2763
|
-
if (stream.path === "/dev/null") return { none: true };
|
|
2764
2896
|
const device = deviceOfStream(stream);
|
|
2765
2897
|
if (device) return device;
|
|
2766
2898
|
return n === 0 ? { input: drain(Fs, stream) } : { capture: true };
|
|
@@ -2975,6 +3107,7 @@ var init_process_signals = __esm({
|
|
|
2975
3107
|
depth = 0;
|
|
2976
3108
|
reporting = false;
|
|
2977
3109
|
unwinding = false;
|
|
3110
|
+
quieted = 0;
|
|
2978
3111
|
raw;
|
|
2979
3112
|
header;
|
|
2980
3113
|
hooks;
|
|
@@ -3019,7 +3152,16 @@ var init_process_signals = __esm({
|
|
|
3019
3152
|
this.reported = { caught, ignored };
|
|
3020
3153
|
this.raw.call({ op: "sig-mask", caught, ignored }, Number.POSITIVE_INFINITY, "sig-mask");
|
|
3021
3154
|
}
|
|
3155
|
+
quiet(fn) {
|
|
3156
|
+
this.quieted++;
|
|
3157
|
+
try {
|
|
3158
|
+
return fn();
|
|
3159
|
+
} finally {
|
|
3160
|
+
this.quieted--;
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3022
3163
|
deliver() {
|
|
3164
|
+
if (this.quieted > 0) return;
|
|
3023
3165
|
const killed = Atomics.load(this.header, SAB_I_KILLED);
|
|
3024
3166
|
if (killed !== 0 && !this.unwinding && this.hooks.killed) {
|
|
3025
3167
|
this.unwinding = true;
|
|
@@ -3265,7 +3407,7 @@ function pidStatus(info) {
|
|
|
3265
3407
|
const ids = `${UID} ${UID} ${UID} ${UID}`;
|
|
3266
3408
|
return [
|
|
3267
3409
|
`Name: ${commOf(info)}`,
|
|
3268
|
-
|
|
3410
|
+
`Umask: ${(info.umask ?? 18).toString(8).padStart(4, "0")}`,
|
|
3269
3411
|
`State: ${state}`,
|
|
3270
3412
|
`Tgid: ${info.pid}`,
|
|
3271
3413
|
"Ngid: 0",
|
|
@@ -3608,9 +3750,15 @@ function kernelSys(transport) {
|
|
|
3608
3750
|
kind(fd) {
|
|
3609
3751
|
return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`))?.kind;
|
|
3610
3752
|
},
|
|
3753
|
+
device(fd) {
|
|
3754
|
+
return json(call2({ op: "fd-info", fd }, `fd-info ${fd}`)).meta;
|
|
3755
|
+
},
|
|
3611
3756
|
size(fd) {
|
|
3612
3757
|
return json(call2({ op: "fd-vfs-stat", fd }, `fd-vfs-stat ${fd}`)).size;
|
|
3613
3758
|
},
|
|
3759
|
+
ttyNames() {
|
|
3760
|
+
return json(call2({ op: "fd-tty-names" }, "fd-tty-names"));
|
|
3761
|
+
},
|
|
3614
3762
|
openTty(name) {
|
|
3615
3763
|
const req = name === void 0 ? { op: "fd-open-tty" } : { op: "fd-open-tty", name };
|
|
3616
3764
|
return json(call2(req, `fd-open-tty ${name ?? ""}`));
|
|
@@ -3683,6 +3831,8 @@ function wireKernelStdio(Fs, streams, sys) {
|
|
|
3683
3831
|
const stream = Fs.getStream(fd);
|
|
3684
3832
|
if (!stream) continue;
|
|
3685
3833
|
const kind = sys?.kind?.(fd);
|
|
3834
|
+
const device = kind === "device" ? sys?.device?.(fd) : void 0;
|
|
3835
|
+
if (device && openDevice(Fs, fd, device)) continue;
|
|
3686
3836
|
if (kind && PLACED.has(kind)) {
|
|
3687
3837
|
const { flags } = stream;
|
|
3688
3838
|
Fs.closeStream(fd);
|
|
@@ -3741,7 +3891,15 @@ async function runWasmProcess(init, port, deps = {}) {
|
|
|
3741
3891
|
}
|
|
3742
3892
|
}
|
|
3743
3893
|
);
|
|
3744
|
-
const
|
|
3894
|
+
const gated = signals.transport();
|
|
3895
|
+
let early = () => {
|
|
3896
|
+
};
|
|
3897
|
+
const transport = {
|
|
3898
|
+
call: (req, timeoutMs, label) => {
|
|
3899
|
+
if (!FS_OPS.has(req.op)) early();
|
|
3900
|
+
return gated.call(req, timeoutMs, label);
|
|
3901
|
+
}
|
|
3902
|
+
};
|
|
3745
3903
|
const sys = kernelSys(transport);
|
|
3746
3904
|
const encoder3 = new TextEncoder();
|
|
3747
3905
|
const say = (fd) => (text) => sys.write(fd, encoder3.encode(`${text}
|
|
@@ -3780,6 +3938,11 @@ async function runWasmProcess(init, port, deps = {}) {
|
|
|
3780
3938
|
}
|
|
3781
3939
|
});
|
|
3782
3940
|
liveParent(imports, () => identify(transport, init).ppid);
|
|
3941
|
+
kernelUmask(imports, {
|
|
3942
|
+
initial: init.umask ?? 18,
|
|
3943
|
+
memory: () => memory,
|
|
3944
|
+
set: (mask) => void transport.call({ op: "proc-umask", mask }, Number.POSITIVE_INFINITY, "umask")
|
|
3945
|
+
});
|
|
3783
3946
|
noFollowUtimes(
|
|
3784
3947
|
imports,
|
|
3785
3948
|
() => ownValue(module, "FS"),
|
|
@@ -3827,6 +3990,7 @@ async function runWasmProcess(init, port, deps = {}) {
|
|
|
3827
3990
|
cwd: init.cwd,
|
|
3828
3991
|
warn: deps.warn ?? say(2)
|
|
3829
3992
|
});
|
|
3993
|
+
early = () => signals.quiet(() => vfs.flushDirty());
|
|
3830
3994
|
const sigpipe = () => running.sliccSigpipe?.() === 1;
|
|
3831
3995
|
const restartable = () => signals.restartable();
|
|
3832
3996
|
const streams = new KernelStreams(running.FS, sys, { sigpipe, restartable });
|
|
@@ -3920,7 +4084,7 @@ function runMain(running, init) {
|
|
|
3920
4084
|
return status2;
|
|
3921
4085
|
}
|
|
3922
4086
|
}
|
|
3923
|
-
var O_RDONLY, O_WRONLY3, O_RDWR3, PLACED, GLUE_TRAILER, evaluateGlue, EVAL_BLOCKED;
|
|
4087
|
+
var FS_OPS, O_RDONLY, O_WRONLY3, O_RDWR3, PLACED, GLUE_TRAILER, evaluateGlue, EVAL_BLOCKED;
|
|
3924
4088
|
var init_process_runtime = __esm({
|
|
3925
4089
|
"src/process/process-runtime.ts"() {
|
|
3926
4090
|
"use strict";
|
|
@@ -3928,6 +4092,7 @@ var init_process_runtime = __esm({
|
|
|
3928
4092
|
init_signals();
|
|
3929
4093
|
init_emscripten_vfs_hook();
|
|
3930
4094
|
init_live_vfs_fs();
|
|
4095
|
+
init_sync_fs_wire();
|
|
3931
4096
|
init_sync_sab_bridge();
|
|
3932
4097
|
init_sync_sab_wire();
|
|
3933
4098
|
init_kernel_streams();
|
|
@@ -3940,6 +4105,7 @@ var init_process_runtime = __esm({
|
|
|
3940
4105
|
init_procfs();
|
|
3941
4106
|
init_realm_user();
|
|
3942
4107
|
init_kernel_streams();
|
|
4108
|
+
FS_OPS = new Set(SYNC_FS_OPS);
|
|
3943
4109
|
O_RDONLY = 0;
|
|
3944
4110
|
O_WRONLY3 = 1;
|
|
3945
4111
|
O_RDWR3 = 2;
|
|
@@ -5077,8 +5243,9 @@ function filestatOf(path, s) {
|
|
|
5077
5243
|
function kernelFiletype(kind) {
|
|
5078
5244
|
switch (kind) {
|
|
5079
5245
|
case "tty":
|
|
5080
|
-
case "device":
|
|
5081
5246
|
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
|
|
5247
|
+
case "device":
|
|
5248
|
+
return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
|
|
5082
5249
|
case "socket":
|
|
5083
5250
|
return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
|
|
5084
5251
|
case "file":
|
|
@@ -5116,7 +5283,7 @@ function wrap(table) {
|
|
|
5116
5283
|
}
|
|
5117
5284
|
return out;
|
|
5118
5285
|
}
|
|
5119
|
-
var WasiExit, NS_PER_MS, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
|
|
5286
|
+
var WasiExit, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
|
|
5120
5287
|
var init_wasi_host = __esm({
|
|
5121
5288
|
"src/process/wasi/wasi-host.ts"() {
|
|
5122
5289
|
"use strict";
|
|
@@ -5133,6 +5300,8 @@ var init_wasi_host = __esm({
|
|
|
5133
5300
|
}
|
|
5134
5301
|
};
|
|
5135
5302
|
NS_PER_MS = 1000000n;
|
|
5303
|
+
AT_SYMLINK_NOFOLLOW2 = 1;
|
|
5304
|
+
DEFAULT_UMASK = 18;
|
|
5136
5305
|
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
|
|
5137
5306
|
MAX_READ = 1024 * 1024;
|
|
5138
5307
|
SIGPIPE_EXIT = 141;
|
|
@@ -5173,6 +5342,43 @@ var init_wasi_host = __esm({
|
|
|
5173
5342
|
get cwd() {
|
|
5174
5343
|
return this.fds.cwd() ?? this.startCwd;
|
|
5175
5344
|
}
|
|
5345
|
+
created(path, mode) {
|
|
5346
|
+
const umask = this.o.kernel.call({ op: "proc-umask" });
|
|
5347
|
+
if (umask !== DEFAULT_UMASK) this.o.fs.chmod(path, mode & ~umask);
|
|
5348
|
+
}
|
|
5349
|
+
sliccFsImports() {
|
|
5350
|
+
const { mem, fds } = this;
|
|
5351
|
+
const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
|
|
5352
|
+
const pathOf = (fd) => {
|
|
5353
|
+
const e = fds.get(fd);
|
|
5354
|
+
if (e.type === "dir") return e.path;
|
|
5355
|
+
if (e.type === "file") return e.file.path;
|
|
5356
|
+
const path = e.type === "kernel" && fds.kind(fd, e) === "file" ? this.kernelStat(fd).path : void 0;
|
|
5357
|
+
if (path === void 0) throw new WasiError("EBADF");
|
|
5358
|
+
return path;
|
|
5359
|
+
};
|
|
5360
|
+
const target = (path, flags) => {
|
|
5361
|
+
if (flags & AT_SYMLINK_NOFOLLOW2 && this.o.fs.lstat(path).isSymbolicLink) {
|
|
5362
|
+
throw new WasiError("ENOTSUP");
|
|
5363
|
+
}
|
|
5364
|
+
return path;
|
|
5365
|
+
};
|
|
5366
|
+
const modeOf = (st) => (st.mode ?? 0) & 4095;
|
|
5367
|
+
return wrap({
|
|
5368
|
+
fd_chmod: (fd, mode) => void this.o.fs.chmod(pathOf(fd), mode & 4095),
|
|
5369
|
+
path_chmod: (dirfd, p, l, mode, flags) => void this.o.fs.chmod(target(at(dirfd, p, l), flags), mode & 4095),
|
|
5370
|
+
umask: (mask, out) => {
|
|
5371
|
+
const old = this.o.kernel.call({ op: "proc-umask", mask });
|
|
5372
|
+
mem.view().setUint32(out, old, true);
|
|
5373
|
+
},
|
|
5374
|
+
fd_mode: (fd, out) => void mem.view().setUint32(out, modeOf(this.o.fs.stat(pathOf(fd))), true),
|
|
5375
|
+
path_mode: (dirfd, p, l, flags, out) => {
|
|
5376
|
+
const path = at(dirfd, p, l);
|
|
5377
|
+
const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
|
|
5378
|
+
mem.view().setUint32(out, modeOf(st), true);
|
|
5379
|
+
}
|
|
5380
|
+
});
|
|
5381
|
+
}
|
|
5176
5382
|
sliccImports() {
|
|
5177
5383
|
const { mem } = this;
|
|
5178
5384
|
const path = (p, l) => {
|
|
@@ -5322,7 +5528,12 @@ var init_wasi_host = __esm({
|
|
|
5322
5528
|
const { mem, fds, o } = this;
|
|
5323
5529
|
const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
|
|
5324
5530
|
return {
|
|
5325
|
-
path_open: (dirfd, _lookup, p, l, oflags, rights, _inheriting, fdflags, out) =>
|
|
5531
|
+
path_open: (dirfd, _lookup, p, l, oflags, rights, _inheriting, fdflags, out) => {
|
|
5532
|
+
const path = at(dirfd, p, l);
|
|
5533
|
+
const fresh = (oflags & OFLAGS.CREAT) !== 0 && !o.fs.exists(path);
|
|
5534
|
+
mem.view().setUint32(out, fds.open(path, oflags, rights, fdflags), true);
|
|
5535
|
+
if (fresh) this.created(path, 438);
|
|
5536
|
+
},
|
|
5326
5537
|
path_filestat_get: (dirfd, lookup, p, l, out) => void this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup)),
|
|
5327
5538
|
path_filestat_set_times: (dirfd, lookup, p, l, atim, mtim, flags) => {
|
|
5328
5539
|
const path = at(dirfd, p, l);
|
|
@@ -5333,6 +5544,7 @@ var init_wasi_host = __esm({
|
|
|
5333
5544
|
const path = at(dirfd, p, l);
|
|
5334
5545
|
if (o.fs.exists(path)) throw new WasiError("EEXIST");
|
|
5335
5546
|
o.fs.mkdir(path);
|
|
5547
|
+
this.created(path, 511);
|
|
5336
5548
|
},
|
|
5337
5549
|
path_remove_directory: (dirfd, p, l) => void o.fs.rmdir(at(dirfd, p, l)),
|
|
5338
5550
|
path_unlink_file: (dirfd, p, l) => {
|
|
@@ -5482,7 +5694,9 @@ var init_wasi_host = __esm({
|
|
|
5482
5694
|
seek(fd, offset, whence) {
|
|
5483
5695
|
const e = this.fds.get(fd);
|
|
5484
5696
|
if (e.type === "kernel") {
|
|
5485
|
-
|
|
5697
|
+
const kind = this.fds.kind(fd, e);
|
|
5698
|
+
if (kind === "device") return 0;
|
|
5699
|
+
if (kind !== "file") throw new WasiError("ESPIPE");
|
|
5486
5700
|
return this.o.kernel.sys.seek(fd, offset, whence);
|
|
5487
5701
|
}
|
|
5488
5702
|
if (e.type === "device") return 0;
|
|
@@ -7426,14 +7640,15 @@ function unsupportedImport(module, memory, extended = false, foreign = {}) {
|
|
|
7426
7640
|
}
|
|
7427
7641
|
return void 0;
|
|
7428
7642
|
}
|
|
7429
|
-
function linkImports(module, preview1, wasix, memory, threads, program = {}, foreign, slicc = {}) {
|
|
7643
|
+
function linkImports(module, preview1, wasix, memory, threads, program = {}, foreign, slicc = {}, sliccFs = {}) {
|
|
7430
7644
|
for (const ns of Object.keys(program)) {
|
|
7431
|
-
if (RESERVED2.has(ns) || ns === SLICC)
|
|
7645
|
+
if (RESERVED2.has(ns) || ns === SLICC || ns === SLICC_FS)
|
|
7432
7646
|
throw new Error(`the imports module may not define ${ns}`);
|
|
7433
7647
|
}
|
|
7434
7648
|
const imports = {
|
|
7435
7649
|
...program,
|
|
7436
7650
|
[SLICC]: { ...slicc },
|
|
7651
|
+
[SLICC_FS]: { ...sliccFs },
|
|
7437
7652
|
[PREVIEW1]: preview1,
|
|
7438
7653
|
...wasix ? { [WASIX]: { ...wasix } } : {},
|
|
7439
7654
|
...threads ? { wasi: { "thread-spawn": (arg) => threads.spawn(arg) } } : {}
|
|
@@ -7560,7 +7775,18 @@ async function instantiate(host, module, memory, threads, {
|
|
|
7560
7775
|
() => instance
|
|
7561
7776
|
);
|
|
7562
7777
|
const slicc = traced(stats, "slicc", host.sliccImports());
|
|
7563
|
-
const
|
|
7778
|
+
const sliccFs = traced(stats, "slicc_fs", host.sliccFsImports());
|
|
7779
|
+
const hostImports = linkImports(
|
|
7780
|
+
module,
|
|
7781
|
+
preview1,
|
|
7782
|
+
wasix,
|
|
7783
|
+
memory,
|
|
7784
|
+
threads,
|
|
7785
|
+
extra,
|
|
7786
|
+
foreign,
|
|
7787
|
+
slicc,
|
|
7788
|
+
sliccFs
|
|
7789
|
+
);
|
|
7564
7790
|
const imports = sync ? merge(hostImports, sync.linker.mainImports(module)) : hostImports;
|
|
7565
7791
|
instance = await WebAssembly.instantiate(module, imports);
|
|
7566
7792
|
stats?.phase("instantiate");
|
|
@@ -7750,7 +7976,7 @@ async function runWasiThread(init, port) {
|
|
|
7750
7976
|
throw e;
|
|
7751
7977
|
}
|
|
7752
7978
|
}
|
|
7753
|
-
var TRAPPED, PREVIEW1, WASIX, SLICC, RESERVED2, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
|
|
7979
|
+
var TRAPPED, PREVIEW1, WASIX, SLICC, SLICC_FS, RESERVED2, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
|
|
7754
7980
|
var init_wasi_runtime = __esm({
|
|
7755
7981
|
"src/process/wasi/wasi-runtime.ts"() {
|
|
7756
7982
|
"use strict";
|
|
@@ -7776,6 +8002,7 @@ var init_wasi_runtime = __esm({
|
|
|
7776
8002
|
PREVIEW1 = "wasi_snapshot_preview1";
|
|
7777
8003
|
WASIX = "wasix_32v1";
|
|
7778
8004
|
SLICC = "slicc";
|
|
8005
|
+
SLICC_FS = "slicc_fs";
|
|
7779
8006
|
RESERVED2 = RESERVED_NAMESPACES;
|
|
7780
8007
|
noErrno = (key) => `imports ${key}: its result cannot carry ENOSYS, and this host does not provide it`;
|
|
7781
8008
|
FALLBACK_MAXIMUM_PAGES = 32768;
|