@ai-ecoverse/slicc-kernel 1.92.0 → 1.93.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 +18 -12
- package/dist/index.js +40 -7
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +856 -208
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +2 -2
- package/dist/node-driver-worker.js +150 -11
- package/dist/node-driver-worker.js.map +4 -4
- package/dist/node-process-worker.js +832 -213
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +944 -217
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1899 -1292
- package/dist/process-worker.js.map +4 -4
- package/package.json +6 -6
package/dist/process-worker.js
CHANGED
|
@@ -104,6 +104,13 @@ var init_lockdown = __esm({
|
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
// src/realm/sync-sab-wire.ts
|
|
107
|
+
function loadBlocked(header) {
|
|
108
|
+
return [Atomics.load(header, SAB_I_BLOCKED), Atomics.load(header, SAB_I_BLOCKED_HI)];
|
|
109
|
+
}
|
|
110
|
+
function storeBlocked(header, [low, high]) {
|
|
111
|
+
Atomics.store(header, SAB_I_BLOCKED_HI, high);
|
|
112
|
+
Atomics.store(header, SAB_I_BLOCKED, low);
|
|
113
|
+
}
|
|
107
114
|
function loadU53(header, lo, hi) {
|
|
108
115
|
return (Atomics.load(header, lo) >>> 0) + Atomics.load(header, hi) * U32;
|
|
109
116
|
}
|
|
@@ -146,7 +153,7 @@ function sabViews(sab) {
|
|
|
146
153
|
window: new Uint8Array(sab, SAB_HEADER_BYTES)
|
|
147
154
|
};
|
|
148
155
|
}
|
|
149
|
-
var SAB_HEADER_I32, SAB_CLOCK_OFFSET, SAB_CLOCK_I64, SAB_HEADER_BYTES, SAB_I_STATE, SAB_I_SEQ, SAB_I_STATUS, SAB_I_TOTAL, SAB_I_CHUNK, SAB_I_OFFSET, SAB_I_REQ, SAB_I_PUB, SAB_I_SIGNALS, SAB_I_TIMERS, SAB_I_MEMORY, SAB_I_TOTAL_HI, SAB_I_OFFSET_HI, SAB_I_KILLED, SAB_I_ASYNC, SAB_I_STOP, SAB_I_BLOCKED, U32, SAB_STATE_IDLE, SAB_STATE_PENDING, SAB_STATE_READY, SAB_STATUS_BYTES, SAB_STATUS_JSON, SAB_STATUS_VOID, SAB_STATUS_ERRNO, SAB_DEFAULT_WINDOW_BYTES, SAB_MIN_BYTES, SYNC_SAB_REQ_MSG, SYNC_SAB_NEXT_MSG, encoder, decoder;
|
|
156
|
+
var SAB_HEADER_I32, SAB_CLOCK_OFFSET, SAB_CLOCK_I64, SAB_HEADER_BYTES, SAB_I_STATE, SAB_I_SEQ, SAB_I_STATUS, SAB_I_TOTAL, SAB_I_CHUNK, SAB_I_OFFSET, SAB_I_REQ, SAB_I_PUB, SAB_I_SIGNALS, SAB_I_TIMERS, SAB_I_MEMORY, SAB_I_TOTAL_HI, SAB_I_OFFSET_HI, SAB_I_KILLED, SAB_I_ASYNC, SAB_I_STOP, SAB_I_BLOCKED, SAB_I_BLOCKED_HI, anyBlocked, U32, SAB_STATE_IDLE, SAB_STATE_PENDING, SAB_STATE_READY, SAB_STATUS_BYTES, SAB_STATUS_JSON, SAB_STATUS_VOID, SAB_STATUS_ERRNO, SAB_DEFAULT_WINDOW_BYTES, SAB_MIN_BYTES, SYNC_SAB_REQ_MSG, SYNC_SAB_NEXT_MSG, encoder, decoder;
|
|
150
157
|
var init_sync_sab_wire = __esm({
|
|
151
158
|
"src/realm/sync-sab-wire.ts"() {
|
|
152
159
|
"use strict";
|
|
@@ -171,6 +178,8 @@ var init_sync_sab_wire = __esm({
|
|
|
171
178
|
SAB_I_ASYNC = 14;
|
|
172
179
|
SAB_I_STOP = 15;
|
|
173
180
|
SAB_I_BLOCKED = 16;
|
|
181
|
+
SAB_I_BLOCKED_HI = 17;
|
|
182
|
+
anyBlocked = (mask) => mask !== void 0 && (mask[0] !== 0 || mask[1] !== 0);
|
|
174
183
|
U32 = 2 ** 32;
|
|
175
184
|
SAB_STATE_IDLE = 0;
|
|
176
185
|
SAB_STATE_PENDING = 1;
|
|
@@ -365,6 +374,73 @@ var init_signals = __esm({
|
|
|
365
374
|
}
|
|
366
375
|
});
|
|
367
376
|
|
|
377
|
+
// src/fs/types.ts
|
|
378
|
+
function normalizePath(path) {
|
|
379
|
+
const parts = [];
|
|
380
|
+
for (const part of path.split("/")) {
|
|
381
|
+
if (part === "" || part === ".") continue;
|
|
382
|
+
if (part === "..") parts.pop();
|
|
383
|
+
else parts.push(part);
|
|
384
|
+
}
|
|
385
|
+
return `/${parts.join("/")}`;
|
|
386
|
+
}
|
|
387
|
+
function inodeOf(path) {
|
|
388
|
+
let h1 = 3735928559;
|
|
389
|
+
let h2 = 1103547991;
|
|
390
|
+
for (let i = 0; i < path.length; i++) {
|
|
391
|
+
const c = path.charCodeAt(i);
|
|
392
|
+
h1 = Math.imul(h1 ^ c, 2654435761);
|
|
393
|
+
h2 = Math.imul(h2 ^ c, 1597334677);
|
|
394
|
+
}
|
|
395
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
396
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
397
|
+
return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;
|
|
398
|
+
}
|
|
399
|
+
var init_types = __esm({
|
|
400
|
+
"src/fs/types.ts"() {
|
|
401
|
+
"use strict";
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// src/fs/owners.ts
|
|
406
|
+
function inGroup(cred, gid) {
|
|
407
|
+
return cred.egid === gid || cred.groups.includes(gid);
|
|
408
|
+
}
|
|
409
|
+
var ROOT_OWNER;
|
|
410
|
+
var init_owners = __esm({
|
|
411
|
+
"src/fs/owners.ts"() {
|
|
412
|
+
"use strict";
|
|
413
|
+
init_types();
|
|
414
|
+
ROOT_OWNER = Object.freeze({ uid: 0, gid: 0 });
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// src/fs/walk.ts
|
|
419
|
+
var init_walk = __esm({
|
|
420
|
+
"src/fs/walk.ts"() {
|
|
421
|
+
"use strict";
|
|
422
|
+
init_types();
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// src/fs/access.ts
|
|
427
|
+
function permits(cred, perm, want, directory = true) {
|
|
428
|
+
const mode = perm.mode ?? (directory ? 493 : 420);
|
|
429
|
+
if (cred.euid === 0) return (want & X_OK) === 0 || directory || (mode & 73) !== 0;
|
|
430
|
+
const shift = cred.euid === perm.uid ? 6 : inGroup(cred, perm.gid) ? 3 : 0;
|
|
431
|
+
return (mode >> shift & want) === want;
|
|
432
|
+
}
|
|
433
|
+
var X_OK;
|
|
434
|
+
var init_access = __esm({
|
|
435
|
+
"src/fs/access.ts"() {
|
|
436
|
+
"use strict";
|
|
437
|
+
init_owners();
|
|
438
|
+
init_types();
|
|
439
|
+
init_walk();
|
|
440
|
+
X_OK = 1;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
368
444
|
// src/fs/pages.ts
|
|
369
445
|
var PAGE, READAHEAD, CLEAN_LIMIT, WRITEBACK, RUN, Pages;
|
|
370
446
|
var init_pages = __esm({
|
|
@@ -619,34 +695,6 @@ var init_ranged = __esm({
|
|
|
619
695
|
}
|
|
620
696
|
});
|
|
621
697
|
|
|
622
|
-
// src/fs/types.ts
|
|
623
|
-
function normalizePath(path) {
|
|
624
|
-
const parts = [];
|
|
625
|
-
for (const part of path.split("/")) {
|
|
626
|
-
if (part === "" || part === ".") continue;
|
|
627
|
-
if (part === "..") parts.pop();
|
|
628
|
-
else parts.push(part);
|
|
629
|
-
}
|
|
630
|
-
return `/${parts.join("/")}`;
|
|
631
|
-
}
|
|
632
|
-
function inodeOf(path) {
|
|
633
|
-
let h1 = 3735928559;
|
|
634
|
-
let h2 = 1103547991;
|
|
635
|
-
for (let i = 0; i < path.length; i++) {
|
|
636
|
-
const c = path.charCodeAt(i);
|
|
637
|
-
h1 = Math.imul(h1 ^ c, 2654435761);
|
|
638
|
-
h2 = Math.imul(h2 ^ c, 1597334677);
|
|
639
|
-
}
|
|
640
|
-
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
641
|
-
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
642
|
-
return 4294967296 * (2097151 & h2) + (h1 >>> 0) || 1;
|
|
643
|
-
}
|
|
644
|
-
var init_types = __esm({
|
|
645
|
-
"src/fs/types.ts"() {
|
|
646
|
-
"use strict";
|
|
647
|
-
}
|
|
648
|
-
});
|
|
649
|
-
|
|
650
698
|
// src/process/wasi/wasi-abi.ts
|
|
651
699
|
function wasiErrnoOf(code2) {
|
|
652
700
|
if (!code2) return E.IO;
|
|
@@ -1071,12 +1119,21 @@ function createSyncFsSabBridge(transport, opts = {}) {
|
|
|
1071
1119
|
lutimes: (path, atimeMs, mtimeMs, now) => {
|
|
1072
1120
|
run({ op: "lutimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
|
|
1073
1121
|
},
|
|
1074
|
-
create: (path, mode) => {
|
|
1075
|
-
|
|
1122
|
+
create: (path, mode, opening2) => {
|
|
1123
|
+
const flags = { ...mode !== void 0 ? { mode } : {}, ...opening2 ? { opening: opening2 } : {} };
|
|
1124
|
+
run({ op: "create", path, ...flags }, path);
|
|
1076
1125
|
},
|
|
1077
|
-
chown: (path, uid, gid, follow2) => {
|
|
1126
|
+
chown: (path, uid, gid, follow2, handle) => {
|
|
1078
1127
|
const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
|
|
1079
|
-
changing(
|
|
1128
|
+
changing(
|
|
1129
|
+
{
|
|
1130
|
+
op: follow2 ? "chown" : "lchown",
|
|
1131
|
+
path,
|
|
1132
|
+
...ids,
|
|
1133
|
+
...handle !== void 0 ? { handle } : {}
|
|
1134
|
+
},
|
|
1135
|
+
path
|
|
1136
|
+
);
|
|
1080
1137
|
},
|
|
1081
1138
|
...opts.owners ? { owners: true } : {},
|
|
1082
1139
|
...opts.links ? { links: true } : {},
|
|
@@ -1153,15 +1210,36 @@ function refusal(err) {
|
|
|
1153
1210
|
function cachedStat(s, dir) {
|
|
1154
1211
|
return s.stat !== void 0 && (!dir || s.statAt === syncCallCount());
|
|
1155
1212
|
}
|
|
1213
|
+
function searchParents(Fs, node, bridge, call2) {
|
|
1214
|
+
const cred = Fs.sliccCred;
|
|
1215
|
+
if (!cred) return;
|
|
1216
|
+
let cur = node.parent;
|
|
1217
|
+
while (cur) {
|
|
1218
|
+
const st = cur.live.stat;
|
|
1219
|
+
if (st && st.uid !== void 0 && st.mode !== void 0) {
|
|
1220
|
+
const perm = { uid: st.uid, gid: st.gid ?? 0, mode: st.mode & 4095 };
|
|
1221
|
+
if (!permits(cred, perm, X_OK, true)) {
|
|
1222
|
+
call2(() => bridge.access?.(liveNodePath(cur), X_OK, "eaccess"));
|
|
1223
|
+
cur.live.stat = void 0;
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
} else {
|
|
1227
|
+
call2(() => bridge.access?.(liveNodePath(cur), X_OK, "eaccess"));
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
if (cur === cur.parent) break;
|
|
1231
|
+
cur = cur.parent;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1156
1234
|
function linkedStates(bridgeOf) {
|
|
1157
1235
|
const opens = /* @__PURE__ */ new Map();
|
|
1158
1236
|
const byId = /* @__PURE__ */ new Map();
|
|
1159
|
-
const
|
|
1237
|
+
const idOf4 = (st) => st?.ino === void 0 || (st.nlink ?? 1) < 2 ? void 0 : `${st.dev}:${st.ino}`;
|
|
1160
1238
|
function know(s, id) {
|
|
1161
1239
|
s.id = id;
|
|
1162
1240
|
if (!byId.has(id)) byId.set(id, s);
|
|
1163
1241
|
}
|
|
1164
|
-
function
|
|
1242
|
+
function opening2(node, on) {
|
|
1165
1243
|
const s = node.live;
|
|
1166
1244
|
if (!on) {
|
|
1167
1245
|
opens.delete(s);
|
|
@@ -1170,14 +1248,14 @@ function linkedStates(bridgeOf) {
|
|
|
1170
1248
|
return;
|
|
1171
1249
|
}
|
|
1172
1250
|
opens.set(s, node);
|
|
1173
|
-
const id =
|
|
1251
|
+
const id = idOf4(s.stat);
|
|
1174
1252
|
if (id !== void 0) know(s, id);
|
|
1175
1253
|
}
|
|
1176
1254
|
function sharedWith(node) {
|
|
1177
1255
|
const st = node.live.stat;
|
|
1178
1256
|
if (st?.ino === void 0) return void 0;
|
|
1179
1257
|
const id = `${st.dev}:${st.ino}`;
|
|
1180
|
-
if (!byId.has(id) &&
|
|
1258
|
+
if (!byId.has(id) && idOf4(st) !== void 0) {
|
|
1181
1259
|
for (const [s2, other] of opens) {
|
|
1182
1260
|
if (s2.id !== void 0 || s2.orphan) continue;
|
|
1183
1261
|
let st2;
|
|
@@ -1185,7 +1263,7 @@ function linkedStates(bridgeOf) {
|
|
|
1185
1263
|
st2 = bridgeOf(other).lstat(liveNodePath(other));
|
|
1186
1264
|
} catch {
|
|
1187
1265
|
}
|
|
1188
|
-
const known =
|
|
1266
|
+
const known = idOf4(st2);
|
|
1189
1267
|
if (known !== void 0) know(s2, known);
|
|
1190
1268
|
}
|
|
1191
1269
|
}
|
|
@@ -1193,7 +1271,7 @@ function linkedStates(bridgeOf) {
|
|
|
1193
1271
|
return s && s !== node.live && !stale(s) ? s : void 0;
|
|
1194
1272
|
}
|
|
1195
1273
|
const holder = (node) => opens.get(node.live) ?? node;
|
|
1196
|
-
return { opening, sharedWith, know, idOf:
|
|
1274
|
+
return { opening: opening2, sharedWith, know, idOf: idOf4, holder };
|
|
1197
1275
|
}
|
|
1198
1276
|
function createHelpers(Fs, ops) {
|
|
1199
1277
|
const bridgeOf = (node) => node.mount.opts.bridge;
|
|
@@ -1415,7 +1493,9 @@ function createNodeOps(h) {
|
|
|
1415
1493
|
const owned = bridgeOf(node).owners === true;
|
|
1416
1494
|
if (owned && Fs.isLink(node.mode) && statOf(node).uid === void 0)
|
|
1417
1495
|
node.live.stat = void 0;
|
|
1496
|
+
const cached = owned && cachedStat(node.live, Fs.isDir(node.mode));
|
|
1418
1497
|
const st = statOf(node);
|
|
1498
|
+
if (cached) searchParents(Fs, node, bridgeOf(node), call2);
|
|
1419
1499
|
const s = node.live;
|
|
1420
1500
|
const size = Fs.isDir(node.mode) ? 4096 : s.ranged?.size() ?? (s.loaded ? s.len : st.size);
|
|
1421
1501
|
const mtime = new Date(st.mtimeMs ?? 0);
|
|
@@ -1478,7 +1558,7 @@ function createNodeOps(h) {
|
|
|
1478
1558
|
if (masked !== DEFAULT_DIR_PERM) metadataCall(() => bridge.chmod(path, masked));
|
|
1479
1559
|
} else if (Fs.isFile(mode)) {
|
|
1480
1560
|
call2(
|
|
1481
|
-
() => bridge.create ? bridge.create(path, perm) : bridge.writeFile(path, new Uint8Array(0))
|
|
1561
|
+
() => bridge.create ? bridge.create(path, perm, opening.get(h.Fs) > 0) : bridge.writeFile(path, new Uint8Array(0))
|
|
1482
1562
|
);
|
|
1483
1563
|
} else {
|
|
1484
1564
|
throw new Fs.ErrnoError(wasiErrno("EPERM"));
|
|
@@ -1724,10 +1804,24 @@ function createStreamOps(h) {
|
|
|
1724
1804
|
}
|
|
1725
1805
|
};
|
|
1726
1806
|
}
|
|
1807
|
+
function countOpens(Fs) {
|
|
1808
|
+
const { open } = Fs;
|
|
1809
|
+
if (typeof open !== "function" || opening.has(Fs)) return;
|
|
1810
|
+
opening.set(Fs, 0);
|
|
1811
|
+
Fs.open = function(...args) {
|
|
1812
|
+
opening.set(Fs, (opening.get(Fs) ?? 0) + 1);
|
|
1813
|
+
try {
|
|
1814
|
+
return open.apply(this, args);
|
|
1815
|
+
} finally {
|
|
1816
|
+
opening.set(Fs, (opening.get(Fs) ?? 1) - 1);
|
|
1817
|
+
}
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1727
1820
|
function createLiveVfsPlugin(Fs) {
|
|
1728
1821
|
const mounts = /* @__PURE__ */ new Set();
|
|
1729
1822
|
const ops = {};
|
|
1730
1823
|
const h = createHelpers(Fs, ops);
|
|
1824
|
+
countOpens(Fs);
|
|
1731
1825
|
const nodeOps = createNodeOps(h);
|
|
1732
1826
|
const streamOps = createStreamOps(h);
|
|
1733
1827
|
ops.node = nodeOps;
|
|
@@ -1860,12 +1954,12 @@ function liveRoot(Fs, bridge) {
|
|
|
1860
1954
|
};
|
|
1861
1955
|
}
|
|
1862
1956
|
function crosses(Fs, from, to) {
|
|
1863
|
-
const
|
|
1957
|
+
const parentOf2 = (path) => Fs.lookupPath?.(path, { parent: true }).node;
|
|
1864
1958
|
const name2 = from.replace(/\/+$/, "").split("/").pop() ?? "";
|
|
1865
1959
|
try {
|
|
1866
|
-
const fromDir =
|
|
1960
|
+
const fromDir = parentOf2(from);
|
|
1867
1961
|
const node = fromDir && Fs.lookupNode?.(fromDir, name2);
|
|
1868
|
-
const dir =
|
|
1962
|
+
const dir = parentOf2(to);
|
|
1869
1963
|
return !!node && !!dir && !!node.live !== !!dir.live;
|
|
1870
1964
|
} catch {
|
|
1871
1965
|
return false;
|
|
@@ -1929,6 +2023,25 @@ function guardRenames(Fs) {
|
|
|
1929
2023
|
function idOf(value2) {
|
|
1930
2024
|
return value2 === -1 || value2 === 4294967295 ? void 0 : value2 >>> 0;
|
|
1931
2025
|
}
|
|
2026
|
+
function chownHeld(Fs, node, s, uid, gid) {
|
|
2027
|
+
const bridge = node.mount.opts.bridge;
|
|
2028
|
+
const handle = s.handle;
|
|
2029
|
+
try {
|
|
2030
|
+
bridge.chown?.(liveNodePath(node), idOf(uid), idOf(gid), false, handle);
|
|
2031
|
+
} catch (err) {
|
|
2032
|
+
throw toErrno(Fs, err);
|
|
2033
|
+
}
|
|
2034
|
+
if (node.parent?.live) node.parent.live.listed = void 0;
|
|
2035
|
+
if (!s.orphan) {
|
|
2036
|
+
s.stat = void 0;
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
try {
|
|
2040
|
+
const st = bridge.keptStat?.(handle);
|
|
2041
|
+
if (st && s.stat) s.stat = { ...s.stat, uid: st.uid, gid: st.gid, mode: st.mode };
|
|
2042
|
+
} catch {
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
1932
2045
|
function useLiveChown(Fs) {
|
|
1933
2046
|
const chown = Fs.chown?.bind(Fs);
|
|
1934
2047
|
if (!chown) return;
|
|
@@ -1947,8 +2060,10 @@ function useLiveChown(Fs) {
|
|
|
1947
2060
|
if (!Fs.fchown || !getStreamChecked) return;
|
|
1948
2061
|
Fs.fchown = (fd, uid, gid) => {
|
|
1949
2062
|
const stream = getStreamChecked.call(Fs, fd);
|
|
1950
|
-
const
|
|
1951
|
-
const
|
|
2063
|
+
const node = stream.node;
|
|
2064
|
+
const s = node.live;
|
|
2065
|
+
if (s?.handle !== void 0 && (!s.orphan || s.kept)) return chownHeld(Fs, node, s, uid, gid);
|
|
2066
|
+
const target = s !== void 0 || stream.path === void 0 ? stream.node : stream.path;
|
|
1952
2067
|
Fs.chown(target, uid, gid);
|
|
1953
2068
|
};
|
|
1954
2069
|
}
|
|
@@ -2009,10 +2124,11 @@ function readingLinks(Fs) {
|
|
|
2009
2124
|
}
|
|
2010
2125
|
};
|
|
2011
2126
|
}
|
|
2012
|
-
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;
|
|
2127
|
+
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, opening;
|
|
2013
2128
|
var init_live_vfs_fs = __esm({
|
|
2014
2129
|
"src/realm/live-vfs-fs.ts"() {
|
|
2015
2130
|
"use strict";
|
|
2131
|
+
init_access();
|
|
2016
2132
|
init_ranged();
|
|
2017
2133
|
init_types();
|
|
2018
2134
|
init_wasi_errno();
|
|
@@ -2031,6 +2147,7 @@ var init_live_vfs_fs = __esm({
|
|
|
2031
2147
|
O_TRUNC = 512;
|
|
2032
2148
|
O_PATH = 2097152;
|
|
2033
2149
|
stale = (s) => !!s.orphan && !s.kept;
|
|
2150
|
+
opening = /* @__PURE__ */ new WeakMap();
|
|
2034
2151
|
}
|
|
2035
2152
|
});
|
|
2036
2153
|
|
|
@@ -2054,6 +2171,22 @@ function topLevelDirs(bridge, warn) {
|
|
|
2054
2171
|
}
|
|
2055
2172
|
return dirs;
|
|
2056
2173
|
}
|
|
2174
|
+
function linuxRmdir(Fs) {
|
|
2175
|
+
const raw = Fs;
|
|
2176
|
+
const { mayDelete, lookupNode } = raw;
|
|
2177
|
+
if (!mayDelete || !lookupNode) return;
|
|
2178
|
+
raw.mayDelete = (dir, name2, isdir) => {
|
|
2179
|
+
const code2 = mayDelete.call(raw, dir, name2, isdir);
|
|
2180
|
+
if (code2 !== 10 || !isdir) return code2;
|
|
2181
|
+
try {
|
|
2182
|
+
const node = lookupNode.call(raw, dir, name2);
|
|
2183
|
+
if (node === node.parent) return 10;
|
|
2184
|
+
} catch {
|
|
2185
|
+
return code2;
|
|
2186
|
+
}
|
|
2187
|
+
return 0;
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2057
2190
|
function mountVfsIntoEmscripten(Fs, deps) {
|
|
2058
2191
|
const { bridge, warn } = deps;
|
|
2059
2192
|
const dirs = topLevelDirs(bridge, warn);
|
|
@@ -2061,6 +2194,8 @@ function mountVfsIntoEmscripten(Fs, deps) {
|
|
|
2061
2194
|
if (dirs) liveRoot(Fs, bridge);
|
|
2062
2195
|
if (bridge.owners && Fs.lookupPath) useLiveChown(Fs);
|
|
2063
2196
|
if (bridge.links && Fs.lookupPath) readingLinks(Fs);
|
|
2197
|
+
linuxRmdir(Fs);
|
|
2198
|
+
if (deps.cred) Fs.sliccCred = deps.cred;
|
|
2064
2199
|
try {
|
|
2065
2200
|
Fs.chdir(deps.cwd);
|
|
2066
2201
|
} catch (err) {
|
|
@@ -2083,309 +2218,1231 @@ var init_emscripten_vfs_hook = __esm({
|
|
|
2083
2218
|
}
|
|
2084
2219
|
});
|
|
2085
2220
|
|
|
2086
|
-
// src/
|
|
2087
|
-
function
|
|
2088
|
-
return
|
|
2221
|
+
// src/fs/dev-removal.ts
|
|
2222
|
+
function inDevTree(path) {
|
|
2223
|
+
return path === "/dev" || path.startsWith("/dev/");
|
|
2089
2224
|
}
|
|
2090
|
-
function
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
return
|
|
2094
|
-
dev: 22,
|
|
2095
|
-
ino: n === void 0 ? 2 : 3 + Number(n),
|
|
2096
|
-
mode: n === void 0 ? 8630 : 8592,
|
|
2097
|
-
nlink: 1,
|
|
2098
|
-
uid: 1e3,
|
|
2099
|
-
gid: 1e3,
|
|
2100
|
-
rdev: n === void 0 ? 5 << 8 | 2 : 136 << 8 | Number(n),
|
|
2101
|
-
size: 0,
|
|
2102
|
-
blksize: 4096,
|
|
2103
|
-
blocks: 0,
|
|
2104
|
-
atime: now,
|
|
2105
|
-
mtime: now,
|
|
2106
|
-
ctime: now
|
|
2107
|
-
};
|
|
2225
|
+
function devRemoval(path, cred) {
|
|
2226
|
+
if (!inDevTree(path)) return void 0;
|
|
2227
|
+
if (cred && cred.euid !== 0) return "EACCES";
|
|
2228
|
+
return path === "/dev" ? "EBUSY" : "EPERM";
|
|
2108
2229
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2230
|
+
var init_dev_removal = __esm({
|
|
2231
|
+
"src/fs/dev-removal.ts"() {
|
|
2232
|
+
"use strict";
|
|
2233
|
+
}
|
|
2234
|
+
});
|
|
2235
|
+
|
|
2236
|
+
// src/process/process-pty.ts
|
|
2237
|
+
function failed(e) {
|
|
2238
|
+
const code2 = e?.code;
|
|
2239
|
+
if (typeof code2 === "string") return -wasiErrno(code2);
|
|
2240
|
+
throw e;
|
|
2241
|
+
}
|
|
2242
|
+
function ptyIoctl(ioctl, deps) {
|
|
2243
|
+
return (fd, op, varargs) => {
|
|
2244
|
+
const request = op >>> 0;
|
|
2245
|
+
if (request !== TIOCGPTN && request !== TIOCSPTLCK && request !== TIOCSCTTY && request !== TIOCSWINSZ && request !== TIOCPKT) {
|
|
2246
|
+
return ioctl(fd, op, varargs);
|
|
2247
|
+
}
|
|
2248
|
+
const stream = deps.fs()?.getStream(fd);
|
|
2249
|
+
const kfd = stream?.sliccKernelFd;
|
|
2250
|
+
if (kfd === void 0) return ioctl(fd, op, varargs);
|
|
2251
|
+
const heap = deps.heap();
|
|
2252
|
+
if (!heap) return -wasiErrno("EFAULT");
|
|
2253
|
+
const argp = (heap[varargs >> 2] ?? 0) >>> 0;
|
|
2254
|
+
try {
|
|
2255
|
+
return answer(request, kfd, argp, heap, deps.kernel);
|
|
2256
|
+
} catch (e) {
|
|
2257
|
+
return failed(e);
|
|
2258
|
+
}
|
|
2125
2259
|
};
|
|
2126
2260
|
}
|
|
2127
|
-
function
|
|
2128
|
-
|
|
2261
|
+
function answer(request, kfd, argp, heap, kernel) {
|
|
2262
|
+
switch (request) {
|
|
2263
|
+
case TIOCGPTN:
|
|
2264
|
+
heap[argp >> 2] = kernel.ptyNumber(kfd);
|
|
2265
|
+
return 0;
|
|
2266
|
+
case TIOCSPTLCK:
|
|
2267
|
+
kernel.ptyLock(kfd, (heap[argp >> 2] ?? 0) !== 0);
|
|
2268
|
+
return 0;
|
|
2269
|
+
case TIOCSCTTY:
|
|
2270
|
+
kernel.setControllingTerminal(kfd);
|
|
2271
|
+
return 0;
|
|
2272
|
+
case TIOCPKT:
|
|
2273
|
+
kernel.setPacketMode(kfd, (heap[argp >> 2] ?? 0) !== 0);
|
|
2274
|
+
return 0;
|
|
2275
|
+
default: {
|
|
2276
|
+
const word = heap[argp >> 2] ?? 0;
|
|
2277
|
+
kernel.setWinsize(kfd, word & 65535, word >>> 16 & 65535);
|
|
2278
|
+
return 0;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2129
2281
|
}
|
|
2130
|
-
var
|
|
2131
|
-
var
|
|
2132
|
-
"src/process/
|
|
2282
|
+
var TIOCGPTN, TIOCSPTLCK, TIOCSCTTY, TIOCSWINSZ, TIOCPKT;
|
|
2283
|
+
var init_process_pty = __esm({
|
|
2284
|
+
"src/process/process-pty.ts"() {
|
|
2133
2285
|
"use strict";
|
|
2134
2286
|
init_wasi_errno();
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2287
|
+
TIOCGPTN = 2147767344;
|
|
2288
|
+
TIOCSPTLCK = 1074025521;
|
|
2289
|
+
TIOCSCTTY = 21518;
|
|
2290
|
+
TIOCSWINSZ = 21524;
|
|
2291
|
+
TIOCPKT = 21536;
|
|
2292
|
+
}
|
|
2293
|
+
});
|
|
2294
|
+
|
|
2295
|
+
// src/process/process-fds.ts
|
|
2296
|
+
function closesOnExec(stream) {
|
|
2297
|
+
return stream.sliccCloexec === true;
|
|
2298
|
+
}
|
|
2299
|
+
function setCloseOnExec(stream, on) {
|
|
2300
|
+
if (on) stream.sliccCloexec = true;
|
|
2301
|
+
else delete stream.sliccCloexec;
|
|
2302
|
+
}
|
|
2303
|
+
function trackCloseOnExec(Fs) {
|
|
2304
|
+
if (tracked.has(Fs)) return;
|
|
2305
|
+
tracked.add(Fs);
|
|
2306
|
+
if (typeof Fs.dupStream === "function") {
|
|
2307
|
+
const dupStream = Fs.dupStream.bind(Fs);
|
|
2308
|
+
Fs.dupStream = (stream, fd) => {
|
|
2309
|
+
const copy2 = dupStream(stream, fd);
|
|
2310
|
+
setCloseOnExec(copy2, false);
|
|
2311
|
+
return copy2;
|
|
2156
2312
|
};
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
constructor(status2) {
|
|
2166
|
-
super(`exit ${status2}`);
|
|
2167
|
-
this.status = status2;
|
|
2168
|
-
}
|
|
2313
|
+
}
|
|
2314
|
+
if (typeof Fs.open === "function") {
|
|
2315
|
+
const open = Fs.open.bind(Fs);
|
|
2316
|
+
Fs.open = (path, flags, mode) => {
|
|
2317
|
+
const cloexec = typeof flags === "number" && (flags & O_CLOEXEC) !== 0;
|
|
2318
|
+
const stream = open(path, cloexec ? flags & ~O_CLOEXEC : flags, mode);
|
|
2319
|
+
setCloseOnExec(stream, cloexec);
|
|
2320
|
+
return stream;
|
|
2169
2321
|
};
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
function marker(deps) {
|
|
2325
|
+
return (fd, on) => {
|
|
2326
|
+
const stream = deps.fs()?.getStream(fd);
|
|
2327
|
+
if (stream) setCloseOnExec(stream, on);
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
function cloexecFcntl(fcntl, deps) {
|
|
2331
|
+
const mark = marker(deps);
|
|
2332
|
+
return (fd, cmd, varargs) => {
|
|
2333
|
+
if (cmd === F_DUPFD_CLOEXEC) {
|
|
2334
|
+
const copy2 = fcntl(fd, F_DUPFD, varargs);
|
|
2335
|
+
if (copy2 >= 0) mark(copy2, true);
|
|
2336
|
+
return copy2;
|
|
2337
|
+
}
|
|
2338
|
+
if (cmd === F_GETFL) {
|
|
2339
|
+
const flags = fcntl(fd, cmd, varargs);
|
|
2340
|
+
return flags < 0 ? flags : flags & ~O_CLOEXEC;
|
|
2341
|
+
}
|
|
2342
|
+
if (cmd !== F_GETFD && cmd !== F_SETFD) return fcntl(fd, cmd, varargs);
|
|
2343
|
+
const stream = deps.fs()?.getStream(fd);
|
|
2344
|
+
if (!stream) return -wasiErrno("EBADF");
|
|
2345
|
+
if (cmd === F_GETFD) return closesOnExec(stream) ? FD_CLOEXEC : 0;
|
|
2346
|
+
const arg = deps.heap()?.[varargs >> 2];
|
|
2347
|
+
if (arg === void 0) return -wasiErrno("EINVAL");
|
|
2348
|
+
setCloseOnExec(stream, (arg & FD_CLOEXEC) !== 0);
|
|
2349
|
+
return 0;
|
|
2350
|
+
};
|
|
2351
|
+
}
|
|
2352
|
+
function cloexecPipe2(pipe2, deps) {
|
|
2353
|
+
const mark = marker(deps);
|
|
2354
|
+
return (fdPtr, flags) => {
|
|
2355
|
+
const r = pipe2(fdPtr, flags & ~O_CLOEXEC);
|
|
2356
|
+
const heap = deps.heap();
|
|
2357
|
+
if (r === 0 && flags & O_CLOEXEC && heap) {
|
|
2358
|
+
mark(heap[fdPtr >> 2], true);
|
|
2359
|
+
mark(heap[(fdPtr >> 2) + 1], true);
|
|
2360
|
+
}
|
|
2361
|
+
return r;
|
|
2362
|
+
};
|
|
2363
|
+
}
|
|
2364
|
+
function quietTarget(dup3, deps) {
|
|
2365
|
+
return (fd = -1, newfd = -1, flags = 0, ...rest2) => {
|
|
2366
|
+
const Fs = deps.fs();
|
|
2367
|
+
const target = fd === newfd || flags !== 0 ? void 0 : Fs?.getStream(newfd);
|
|
2368
|
+
if (target && Fs?.getStream(fd)) {
|
|
2369
|
+
try {
|
|
2370
|
+
Fs.close?.(target);
|
|
2371
|
+
} catch {
|
|
2175
2372
|
}
|
|
2373
|
+
}
|
|
2374
|
+
return dup3(fd, newfd, flags, ...rest2);
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
2377
|
+
function cloexecByFlag(syscall, flagArg, deps) {
|
|
2378
|
+
const mark = marker(deps);
|
|
2379
|
+
return (...args) => {
|
|
2380
|
+
const cloexec = ((args[flagArg] ?? 0) & O_CLOEXEC) !== 0;
|
|
2381
|
+
if (cloexec) args[flagArg] = args[flagArg] & ~O_CLOEXEC;
|
|
2382
|
+
const fd = syscall(...args);
|
|
2383
|
+
if (fd >= 0) mark(fd, cloexec);
|
|
2384
|
+
return fd;
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2387
|
+
function wrapperFactories(deps) {
|
|
2388
|
+
const { pty, timer } = deps;
|
|
2389
|
+
return {
|
|
2390
|
+
...timer ? { setitimer: (f) => kernelTimer(f, timer) } : {},
|
|
2391
|
+
fcntl: (f) => cloexecFcntl(f, deps),
|
|
2392
|
+
pipe2: (f) => cloexecPipe2(f, deps),
|
|
2393
|
+
dup3: (f) => cloexecByFlag(quietTarget(f, deps), 2, deps),
|
|
2394
|
+
socket: (f) => cloexecByFlag(f, 1, deps),
|
|
2395
|
+
accept4: (f) => cloexecByFlag(f, 3, deps),
|
|
2396
|
+
...pty ? { ioctl: (f) => ptyIoctl(f, { fs: deps.fs, heap: deps.heap, kernel: pty }) } : {}
|
|
2397
|
+
};
|
|
2398
|
+
}
|
|
2399
|
+
function kernelTimer(setitimer, timer) {
|
|
2400
|
+
return (which, ms) => {
|
|
2401
|
+
if (which !== 0) return setitimer(which, ms);
|
|
2402
|
+
timer.arm(ms ?? 0);
|
|
2403
|
+
return 0;
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
function syscallOf(glue, name2, value2) {
|
|
2407
|
+
const names = Object.keys(IMPORT_NAMES);
|
|
2408
|
+
const own = names.find((key) => glue[key] !== void 0 && glue[key] === value2);
|
|
2409
|
+
if (own) return own;
|
|
2410
|
+
return typeof value2 === "function" ? names.find((key) => glue[key] !== void 0 && IMPORT_NAMES[key] === name2) : void 0;
|
|
2411
|
+
}
|
|
2412
|
+
function wrapCloexecSyscalls(imports, glue, deps) {
|
|
2413
|
+
if (!glue) return;
|
|
2414
|
+
const factories = wrapperFactories(deps);
|
|
2415
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2416
|
+
for (const namespace of Object.values(imports)) {
|
|
2417
|
+
if (!namespace || typeof namespace !== "object" || seen.has(namespace)) continue;
|
|
2418
|
+
seen.add(namespace);
|
|
2419
|
+
for (const [name2, value2] of Object.entries(namespace)) {
|
|
2420
|
+
const key = syscallOf(glue, name2, value2);
|
|
2421
|
+
const wrap2 = key && factories[key];
|
|
2422
|
+
if (wrap2) namespace[name2] = wrap2(value2);
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
function pathOpensLinks(Fs) {
|
|
2427
|
+
const fs = Fs;
|
|
2428
|
+
const { mayOpen, isLink } = fs;
|
|
2429
|
+
if (!mayOpen || !isLink) return;
|
|
2430
|
+
fs.mayOpen = (node, flags) => flags & O_PATH2 && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
|
|
2431
|
+
}
|
|
2432
|
+
function importKey(namespace, name2, glue) {
|
|
2433
|
+
const own = glue?.[name2];
|
|
2434
|
+
if (typeof own === "function") {
|
|
2435
|
+
const found = Object.keys(namespace).find((k) => namespace[k] === own);
|
|
2436
|
+
if (found !== void 0) return found;
|
|
2437
|
+
}
|
|
2438
|
+
const literal = LITERALS[name2];
|
|
2439
|
+
return typeof namespace[literal] === "function" ? literal : void 0;
|
|
2440
|
+
}
|
|
2441
|
+
function wrapImport(imports, name2, glue, wrap2, optional = false) {
|
|
2442
|
+
let wrapped = false;
|
|
2443
|
+
for (const ns of namespaces(imports)) {
|
|
2444
|
+
const key = importKey(ns, name2, glue);
|
|
2445
|
+
if (key === void 0) continue;
|
|
2446
|
+
ns[key] = wrap2(ns[key]);
|
|
2447
|
+
wrapped = true;
|
|
2448
|
+
}
|
|
2449
|
+
if (!wrapped && !optional && typeof glue?.[name2] === "function") {
|
|
2450
|
+
throw new Error(`slicc-kernel cannot find the glue's ${LITERALS[name2]} among its imports`);
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
function kernelUmask(imports, deps) {
|
|
2454
|
+
let umask = deps.initial & 511;
|
|
2455
|
+
const { glue } = deps;
|
|
2456
|
+
wrapImport(imports, "openat", glue, (openat) => (dirfd, path, flags, varargs) => {
|
|
2457
|
+
const memory = deps.memory();
|
|
2458
|
+
if (flags & O_CREAT && varargs && memory) new Int32Array(memory.buffer)[varargs >> 2] &= ~umask;
|
|
2459
|
+
return openat(dirfd, path, flags, varargs);
|
|
2460
|
+
});
|
|
2461
|
+
wrapImport(
|
|
2462
|
+
imports,
|
|
2463
|
+
"mkdirat",
|
|
2464
|
+
glue,
|
|
2465
|
+
(mkdirat) => (dirfd, path, mode) => mkdirat(dirfd, path, mode & ~umask)
|
|
2466
|
+
);
|
|
2467
|
+
wrapImport(
|
|
2468
|
+
imports,
|
|
2469
|
+
"mknodat",
|
|
2470
|
+
glue,
|
|
2471
|
+
(mknodat) => (dirfd, path, mode, dev) => mknodat(dirfd, path, mode & ~umask, dev)
|
|
2472
|
+
);
|
|
2473
|
+
wrapImport(imports, "umask", glue, (own) => {
|
|
2474
|
+
own(umask);
|
|
2475
|
+
return (mask) => {
|
|
2476
|
+
const old = umask;
|
|
2477
|
+
umask = mask & 511;
|
|
2478
|
+
own(umask);
|
|
2479
|
+
deps.set(umask);
|
|
2480
|
+
return old;
|
|
2176
2481
|
};
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
stream.flags = flags;
|
|
2207
|
-
return stream;
|
|
2208
|
-
}
|
|
2209
|
-
const createNode = fs.createNode;
|
|
2210
|
-
this.socketRoot ??= fs.mount({ mount: () => createNode(null, "/", 16895, 0) }, {}, null);
|
|
2211
|
-
const ino = ++this.sockets;
|
|
2212
|
-
const node = fs.createNode(this.socketRoot, `socket:${ino}`, SOCKET_MODE, 0);
|
|
2213
|
-
const now = /* @__PURE__ */ new Date();
|
|
2214
|
-
const stat = { dev: 0, ino, mode: SOCKET_MODE, nlink: 1, uid: 0, gid: 0, rdev: 0, size: 0 };
|
|
2215
|
-
const times = { atime: now, mtime: now, ctime: now, blksize: 4096, blocks: 0 };
|
|
2216
|
-
node.node_ops = { getattr: () => ({ ...stat, ...times }) };
|
|
2217
|
-
return fs.createStream({ node, flags, seekable: false, position: 0, stream_ops: {} });
|
|
2482
|
+
});
|
|
2483
|
+
}
|
|
2484
|
+
function touching(times, memory) {
|
|
2485
|
+
if (times === 0) return true;
|
|
2486
|
+
if (!memory) return false;
|
|
2487
|
+
const heap = new Int32Array(memory.buffer);
|
|
2488
|
+
const nsec = [heap[times + 8 >> 2], heap[times + 24 >> 2]];
|
|
2489
|
+
return nsec.every((n) => n === UTIME_NOW || n === UTIME_OMIT);
|
|
2490
|
+
}
|
|
2491
|
+
function touch(Fs, on, run) {
|
|
2492
|
+
if (!Fs || !on) return run();
|
|
2493
|
+
Fs.sliccTouch = true;
|
|
2494
|
+
try {
|
|
2495
|
+
return run();
|
|
2496
|
+
} finally {
|
|
2497
|
+
Fs.sliccTouch = void 0;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
function noFollowUtimes(imports, fs, glue, memory = () => void 0) {
|
|
2501
|
+
wrapImport(
|
|
2502
|
+
imports,
|
|
2503
|
+
"utimensat",
|
|
2504
|
+
{ utimensat: glue },
|
|
2505
|
+
(utimensat) => (dirfd, path, times, flags) => {
|
|
2506
|
+
const Fs = fs();
|
|
2507
|
+
const on = touching(times, memory());
|
|
2508
|
+
const { utime, lookupPath, ErrnoError } = Fs ?? {};
|
|
2509
|
+
if (!Fs || !(flags & AT_SYMLINK_NOFOLLOW) || !utime || !lookupPath || !ErrnoError) {
|
|
2510
|
+
return touch(Fs, on, () => utimensat(dirfd, path, times, flags));
|
|
2218
2511
|
}
|
|
2219
|
-
|
|
2220
|
-
const
|
|
2221
|
-
if (!
|
|
2222
|
-
|
|
2223
|
-
|
|
2512
|
+
Fs.utime = (at, atime, mtime) => {
|
|
2513
|
+
const { node } = lookupPath.call(Fs, at, { follow: false });
|
|
2514
|
+
if (!node.node_ops.setattr) throw new ErrnoError(EMSCRIPTEN_EPERM);
|
|
2515
|
+
node.node_ops.setattr(node, { atime, mtime });
|
|
2516
|
+
};
|
|
2517
|
+
try {
|
|
2518
|
+
return touch(Fs, on, () => utimensat(dirfd, path, times, flags));
|
|
2519
|
+
} finally {
|
|
2520
|
+
Fs.utime = utime;
|
|
2224
2521
|
}
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2522
|
+
}
|
|
2523
|
+
);
|
|
2524
|
+
}
|
|
2525
|
+
function errnoOf(err) {
|
|
2526
|
+
const { errno: errno2, code: code2 } = err ?? {};
|
|
2527
|
+
if (typeof errno2 === "number") return errno2;
|
|
2528
|
+
if (typeof code2 === "string") return wasiErrno(code2);
|
|
2529
|
+
throw err;
|
|
2530
|
+
}
|
|
2531
|
+
function persistsItself(stream) {
|
|
2532
|
+
const type = stream.node.mount?.type;
|
|
2533
|
+
return typeof type?.syncfs === "function";
|
|
2534
|
+
}
|
|
2535
|
+
function namespaces(imports) {
|
|
2536
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2537
|
+
for (const namespace of Object.values(imports)) {
|
|
2538
|
+
if (namespace && typeof namespace === "object") seen.add(namespace);
|
|
2539
|
+
}
|
|
2540
|
+
return [...seen];
|
|
2541
|
+
}
|
|
2542
|
+
function keyOf(namespace, name2, glue) {
|
|
2543
|
+
const own = glue?.[name2];
|
|
2544
|
+
const found = typeof own === "function" ? Object.keys(namespace).find((k) => namespace[k] === own) : void 0;
|
|
2545
|
+
return found ?? (typeof namespace[name2] === "function" ? name2 : void 0);
|
|
2546
|
+
}
|
|
2547
|
+
function syncFsync(imports, fs, glue) {
|
|
2548
|
+
for (const namespace of namespaces(imports)) {
|
|
2549
|
+
const key = keyOf(namespace, "fd_sync", glue);
|
|
2550
|
+
const original = key === void 0 ? void 0 : namespace[key];
|
|
2551
|
+
if (key === void 0 || !original?.isAsync) continue;
|
|
2552
|
+
namespace[key] = (fd) => {
|
|
2553
|
+
const stream = fs()?.getStream(fd);
|
|
2554
|
+
if (!stream) return EBADF;
|
|
2555
|
+
if (persistsItself(stream)) return original(fd);
|
|
2556
|
+
try {
|
|
2557
|
+
const result = stream.stream_ops.fsync?.(stream);
|
|
2558
|
+
return typeof result === "number" ? result : 0;
|
|
2559
|
+
} catch (err) {
|
|
2560
|
+
return errnoOf(err);
|
|
2230
2561
|
}
|
|
2231
|
-
|
|
2232
|
-
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
function offsetOf(rest2) {
|
|
2566
|
+
const at = rest2.length >= 3 ? Number(rest2[1]) * 2 ** 32 + (Number(rest2[0]) >>> 0) : Number(BigInt.asIntN(64, BigInt(rest2[0])));
|
|
2567
|
+
return at >= 0 && Number.isSafeInteger(at) ? at : void 0;
|
|
2568
|
+
}
|
|
2569
|
+
function readInto(sys, kfd, target, at) {
|
|
2570
|
+
let done = 0;
|
|
2571
|
+
while (done < target.length) {
|
|
2572
|
+
const got = sys.pread?.(kfd, target.length - done, at + done) ?? new Uint8Array(0);
|
|
2573
|
+
if (got.length === 0) break;
|
|
2574
|
+
target.set(got, done);
|
|
2575
|
+
done += got.length;
|
|
2576
|
+
}
|
|
2577
|
+
return done;
|
|
2578
|
+
}
|
|
2579
|
+
function positioned(original, write2, deps) {
|
|
2580
|
+
return (fd, iov, iovcnt, ...rest2) => {
|
|
2581
|
+
const stream = deps.fs()?.getStream(Number(fd));
|
|
2582
|
+
const memory = deps.memory();
|
|
2583
|
+
const kfd = stream?.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
2584
|
+
if (kfd === void 0 || !memory || !(write2 ? deps.sys.pwrite : deps.sys.pread)) {
|
|
2585
|
+
return original(fd, iov, iovcnt, ...rest2);
|
|
2586
|
+
}
|
|
2587
|
+
const at = offsetOf(rest2);
|
|
2588
|
+
if (at === void 0) return wasiErrno("EINVAL");
|
|
2589
|
+
const view = new DataView(memory.buffer);
|
|
2590
|
+
let done = 0;
|
|
2591
|
+
try {
|
|
2592
|
+
for (let i = 0; i < Number(iovcnt); i++) {
|
|
2593
|
+
const ptr = view.getUint32(Number(iov) + i * 8, true);
|
|
2594
|
+
const len = view.getUint32(Number(iov) + i * 8 + 4, true);
|
|
2595
|
+
const part = new Uint8Array(memory.buffer, ptr, len);
|
|
2596
|
+
const moved = write2 ? deps.sys.pwrite?.(kfd, part.slice(), at + done) ?? 0 : readInto(deps.sys, kfd, part, at + done);
|
|
2597
|
+
done += moved;
|
|
2598
|
+
if (moved < len) break;
|
|
2233
2599
|
}
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
const node = mkdev.call(fs, path, dev);
|
|
2251
|
-
if (typeof node === "object" && node !== null) {
|
|
2252
|
-
const made = node;
|
|
2253
|
-
made.node_ops = { ...made.node_ops, getattr: () => sealedStat(minor) };
|
|
2254
|
-
}
|
|
2255
|
-
} catch {
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2600
|
+
} catch (err) {
|
|
2601
|
+
return errnoOf(err);
|
|
2602
|
+
}
|
|
2603
|
+
view.setUint32(Number(rest2[rest2.length - 1]), done, true);
|
|
2604
|
+
return 0;
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
function positionalIo(imports, deps) {
|
|
2608
|
+
for (const namespace of namespaces(imports)) {
|
|
2609
|
+
for (const [name2, write2] of [
|
|
2610
|
+
["fd_pread", false],
|
|
2611
|
+
["fd_pwrite", true]
|
|
2612
|
+
]) {
|
|
2613
|
+
const key = keyOf(namespace, name2, deps.glue);
|
|
2614
|
+
if (key !== void 0) {
|
|
2615
|
+
namespace[key] = positioned(namespace[key], write2, deps);
|
|
2258
2616
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
function staging(Fs, length) {
|
|
2621
|
+
try {
|
|
2622
|
+
return new Uint8Array(length);
|
|
2623
|
+
} catch {
|
|
2624
|
+
throw new Fs.ErrnoError(wasiErrno("ENOMEM"));
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
function useFileMmap(Fs, deps) {
|
|
2628
|
+
const fs = Fs;
|
|
2629
|
+
const mmap = fs.mmap;
|
|
2630
|
+
if (typeof mmap !== "function") return;
|
|
2631
|
+
fs.mmap = (stream, length, position, prot, flags) => {
|
|
2632
|
+
const memalign = deps.memalign();
|
|
2633
|
+
const memory = deps.memory();
|
|
2634
|
+
const shared = (flags & MAP_TYPE) !== MAP_PRIVATE && (prot & PROT_WRITE) !== 0;
|
|
2635
|
+
const kfd = stream.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
2636
|
+
if (shared && kfd !== void 0) throw new Fs.ErrnoError(wasiErrno("ENODEV"));
|
|
2637
|
+
if (stream.stream_ops.mmap && kfd === void 0 || !memalign || !memory || length <= 0 || shared || (stream.flags & O_ACCMODE2) === O_WRONLY || !Fs.isFile(stream.node.mode)) {
|
|
2638
|
+
return mmap.call(fs, stream, length, position, prot, flags);
|
|
2639
|
+
}
|
|
2640
|
+
const data = staging(Fs, length);
|
|
2641
|
+
let done = 0;
|
|
2642
|
+
try {
|
|
2643
|
+
if (kfd !== void 0) done = readInto(deps.sys, kfd, data, position);
|
|
2644
|
+
else {
|
|
2645
|
+
for (let got = 1; done < length && got > 0; done += got) {
|
|
2646
|
+
got = Fs.read(stream, data, done, length - done, position + done);
|
|
2266
2647
|
}
|
|
2267
|
-
this.attach(stream, kfd, false);
|
|
2268
|
-
this.nameStream(stream, path);
|
|
2269
|
-
if (path === CLIPBOARD_PATH) this.reportClose(kfd);
|
|
2270
2648
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2649
|
+
} catch (err) {
|
|
2650
|
+
throw new Fs.ErrnoError(errnoOf(err));
|
|
2651
|
+
}
|
|
2652
|
+
const size = Math.ceil(length / MAP_ALIGN) * MAP_ALIGN;
|
|
2653
|
+
const ptr = memalign(MAP_ALIGN, size);
|
|
2654
|
+
if (!ptr) throw new Fs.ErrnoError(wasiErrno("ENOMEM"));
|
|
2655
|
+
const target = new Uint8Array(memory.buffer, ptr, size);
|
|
2656
|
+
target.fill(0);
|
|
2657
|
+
target.set(data.subarray(0, done));
|
|
2658
|
+
return { ptr, allocated: true };
|
|
2659
|
+
};
|
|
2660
|
+
}
|
|
2661
|
+
function wasmMemory(instance, imports) {
|
|
2662
|
+
const isMemory = (v) => v instanceof WebAssembly.Memory;
|
|
2663
|
+
const exported = Object.values(instance.exports).find(isMemory);
|
|
2664
|
+
if (exported) return exported;
|
|
2665
|
+
for (const namespace of Object.values(imports)) {
|
|
2666
|
+
const found = Object.values(namespace ?? {}).find(isMemory);
|
|
2667
|
+
if (found) return found;
|
|
2668
|
+
}
|
|
2669
|
+
return void 0;
|
|
2670
|
+
}
|
|
2671
|
+
function absoluteOf(path, cwd) {
|
|
2672
|
+
const parts = [];
|
|
2673
|
+
for (const part of `${path.startsWith("/") ? "" : cwd}/${path}`.split("/")) {
|
|
2674
|
+
if (part === "" || part === ".") continue;
|
|
2675
|
+
if (part === "..") parts.pop();
|
|
2676
|
+
else parts.push(part);
|
|
2677
|
+
}
|
|
2678
|
+
return `/${parts.join("/")}`;
|
|
2679
|
+
}
|
|
2680
|
+
function fdOfPath(path, cwd) {
|
|
2681
|
+
const abs = absoluteOf(path, cwd);
|
|
2682
|
+
const std = ["/dev/stdin", "/dev/stdout", "/dev/stderr"].indexOf(abs);
|
|
2683
|
+
if (std >= 0) return std;
|
|
2684
|
+
const m = /^\/(?:dev|proc\/self)\/fd\/(\d+)$/.exec(abs);
|
|
2685
|
+
return m ? Number(m[1]) : void 0;
|
|
2686
|
+
}
|
|
2687
|
+
function syntheticAttr(mode, ino) {
|
|
2688
|
+
const now = /* @__PURE__ */ new Date();
|
|
2689
|
+
return {
|
|
2690
|
+
dev: 1,
|
|
2691
|
+
ino,
|
|
2692
|
+
mode,
|
|
2693
|
+
nlink: 1,
|
|
2694
|
+
uid: 0,
|
|
2695
|
+
gid: 0,
|
|
2696
|
+
rdev: 0,
|
|
2697
|
+
size: 0,
|
|
2698
|
+
atime: now,
|
|
2699
|
+
mtime: now,
|
|
2700
|
+
ctime: now,
|
|
2701
|
+
blksize: 4096,
|
|
2702
|
+
blocks: 0
|
|
2703
|
+
};
|
|
2704
|
+
}
|
|
2705
|
+
function describeFdDir(Fs) {
|
|
2706
|
+
let dir;
|
|
2707
|
+
try {
|
|
2708
|
+
dir = Fs.lookupPath?.("/proc/self/fd", { follow: true })?.node;
|
|
2709
|
+
} catch {
|
|
2710
|
+
return;
|
|
2711
|
+
}
|
|
2712
|
+
const ops = dir?.node_ops;
|
|
2713
|
+
const lookup2 = ops?.lookup;
|
|
2714
|
+
if (!dir || !lookup2 || ops.getattr) return;
|
|
2715
|
+
dir.node_ops = {
|
|
2716
|
+
...ops,
|
|
2717
|
+
getattr: () => syntheticAttr(DIR_MODE, 1),
|
|
2718
|
+
lookup: (parent, name2) => {
|
|
2719
|
+
const entry = lookup2(parent, name2);
|
|
2720
|
+
entry.node_ops = {
|
|
2721
|
+
...entry.node_ops,
|
|
2722
|
+
getattr: () => syntheticAttr(LINK_MODE, entry.id ?? 0)
|
|
2723
|
+
};
|
|
2724
|
+
return entry;
|
|
2725
|
+
}
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
function useZeroDevices(Fs) {
|
|
2729
|
+
const { analyzePath, registerDevice, mkdev, makedev } = Fs;
|
|
2730
|
+
if (!analyzePath || !registerDevice || !mkdev || !makedev) return;
|
|
2731
|
+
const zeros = (_s, buffer, offset, length) => {
|
|
2732
|
+
buffer.fill(0, offset, offset + length);
|
|
2733
|
+
return length;
|
|
2734
|
+
};
|
|
2735
|
+
const devices = [
|
|
2736
|
+
["/dev/zero", 5, (_s, _b, _o, length) => length],
|
|
2737
|
+
[
|
|
2738
|
+
"/dev/full",
|
|
2739
|
+
7,
|
|
2740
|
+
(_s, _b, _o, length) => {
|
|
2741
|
+
if (length > 0) throw new Fs.ErrnoError(wasiErrno("ENOSPC"));
|
|
2742
|
+
return 0;
|
|
2274
2743
|
}
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2744
|
+
]
|
|
2745
|
+
];
|
|
2746
|
+
for (const [path, minor, write2] of devices) {
|
|
2747
|
+
if (analyzePath.call(Fs, path).exists) continue;
|
|
2748
|
+
const dev = makedev.call(Fs, 1, minor);
|
|
2749
|
+
registerDevice.call(Fs, dev, { read: zeros, write: write2, llseek: () => 0 });
|
|
2750
|
+
mkdev.call(Fs, path, CHAR_DEVICE, dev);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
function useDevRemoval(Fs) {
|
|
2754
|
+
const fs = Fs;
|
|
2755
|
+
for (const name2 of ["unlink", "rmdir"]) {
|
|
2756
|
+
const remove = fs[name2];
|
|
2757
|
+
if (typeof remove !== "function") continue;
|
|
2758
|
+
fs[name2] = (path) => {
|
|
2759
|
+
const refused = devRemoval(absoluteOf(path, Fs.cwd()), fs.sliccCred);
|
|
2760
|
+
if (refused) throw new Fs.ErrnoError(wasiErrno(refused));
|
|
2761
|
+
remove.call(Fs, path);
|
|
2762
|
+
};
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
function linkStdio(Fs) {
|
|
2766
|
+
const { unlink, symlink } = Fs;
|
|
2767
|
+
if (!unlink || !symlink) return;
|
|
2768
|
+
for (const [fd, name2] of ["stdin", "stdout", "stderr"].entries()) {
|
|
2769
|
+
try {
|
|
2770
|
+
unlink.call(Fs, `/dev/${name2}`);
|
|
2771
|
+
} catch {
|
|
2772
|
+
}
|
|
2773
|
+
try {
|
|
2774
|
+
symlink.call(Fs, `/proc/self/fd/${fd}`, `/dev/${name2}`);
|
|
2775
|
+
} catch {
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
function useDevFd(Fs) {
|
|
2780
|
+
if (typeof Fs.open !== "function") return;
|
|
2781
|
+
try {
|
|
2782
|
+
Fs.symlink?.("/proc/self/fd", "/dev/fd");
|
|
2783
|
+
} catch {
|
|
2784
|
+
}
|
|
2785
|
+
linkStdio(Fs);
|
|
2786
|
+
describeFdDir(Fs);
|
|
2787
|
+
const fdOf = (path) => typeof path === "string" ? fdOfPath(path, Fs.cwd()) : void 0;
|
|
2788
|
+
const target = (fd) => {
|
|
2789
|
+
const stream = Fs.getStream(fd);
|
|
2790
|
+
if (!stream) throw new Fs.ErrnoError(wasiErrno("EBADF"));
|
|
2791
|
+
return stream;
|
|
2792
|
+
};
|
|
2793
|
+
const open = Fs.open.bind(Fs);
|
|
2794
|
+
Fs.open = (path, flags, mode) => {
|
|
2795
|
+
const fd = fdOf(path);
|
|
2796
|
+
if (fd === void 0) return open(path, flags, mode);
|
|
2797
|
+
const copy2 = Fs.dupStream(target(fd), -1);
|
|
2798
|
+
setCloseOnExec(copy2, typeof flags === "number" && (flags & O_CLOEXEC) !== 0);
|
|
2799
|
+
return copy2;
|
|
2800
|
+
};
|
|
2801
|
+
const { stat, fstat } = Fs;
|
|
2802
|
+
if (typeof stat !== "function" || typeof fstat !== "function") return;
|
|
2803
|
+
Fs.stat = (path, dontFollow) => {
|
|
2804
|
+
const fd = dontFollow ? void 0 : fdOf(path);
|
|
2805
|
+
if (fd === void 0) return stat.call(Fs, path, dontFollow);
|
|
2806
|
+
target(fd);
|
|
2807
|
+
return fstat.call(Fs, fd);
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
function pinRootKind() {
|
|
2811
|
+
pinnedRoot = rootKind();
|
|
2812
|
+
}
|
|
2813
|
+
function mountTable(mounts = []) {
|
|
2814
|
+
const root = pinnedRoot ?? rootKind();
|
|
2815
|
+
const lines = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
2816
|
+
for (const m of mounts) {
|
|
2817
|
+
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
2818
|
+
if (m.state !== "ok") options.push(m.state);
|
|
2819
|
+
const access = options.includes("ro") ? [] : ["rw"];
|
|
2820
|
+
lines.push(
|
|
2821
|
+
`${field(m.source)} ${field(m.target)} ${m.type} ${[...access, ...options].join(",")} 0 0`
|
|
2822
|
+
);
|
|
2823
|
+
}
|
|
2824
|
+
return `${lines.join("\n")}
|
|
2313
2825
|
`;
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2826
|
+
}
|
|
2827
|
+
function accounts(env = {}) {
|
|
2828
|
+
const user = env.USER ?? "web_user";
|
|
2829
|
+
const name2 = NAME.test(user) && user !== "root" ? user : "user";
|
|
2830
|
+
const home = env.HOME || "/home";
|
|
2831
|
+
return {
|
|
2832
|
+
passwd: `root:x:0:0:root:/root:/bin/sh
|
|
2833
|
+
${name2}:x:1000:1000:${name2}:${home}:/bin/bash
|
|
2834
|
+
`,
|
|
2835
|
+
group: `root:x:0:
|
|
2836
|
+
${name2}:x:1000:
|
|
2837
|
+
`
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
function useMounts(Fs, env = {}, live = false) {
|
|
2841
|
+
const { writeFile, mkdirTree } = Fs;
|
|
2842
|
+
if (typeof Fs.open !== "function" || typeof writeFile !== "function") return;
|
|
2843
|
+
const { passwd, group } = accounts(env);
|
|
2844
|
+
const backing = { "/etc/mtab": "/proc/mounts" };
|
|
2845
|
+
try {
|
|
2846
|
+
if (!live) writeFile.call(Fs, "/proc/mounts", mountTable());
|
|
2847
|
+
} catch {
|
|
2848
|
+
return;
|
|
2849
|
+
}
|
|
2850
|
+
try {
|
|
2851
|
+
mkdirTree.call(Fs, "/dev/.etc");
|
|
2852
|
+
writeFile.call(Fs, "/dev/.etc/passwd", passwd);
|
|
2853
|
+
writeFile.call(Fs, "/dev/.etc/group", group);
|
|
2854
|
+
writeFile.call(Fs, "/dev/.etc/hosts", hostsFile(hostnameOf(env)));
|
|
2855
|
+
writeFile.call(Fs, "/dev/.etc/hostname", `${hostnameOf(env)}
|
|
2856
|
+
`);
|
|
2857
|
+
backing["/etc/passwd"] = "/dev/.etc/passwd";
|
|
2858
|
+
backing["/etc/group"] = "/dev/.etc/group";
|
|
2859
|
+
backing["/etc/hosts"] = "/dev/.etc/hosts";
|
|
2860
|
+
backing["/etc/hostname"] = "/dev/.etc/hostname";
|
|
2861
|
+
} catch {
|
|
2862
|
+
}
|
|
2863
|
+
const open = Fs.open.bind(Fs);
|
|
2864
|
+
Fs.open = (path, flags, mode) => {
|
|
2865
|
+
const instead = backing[path];
|
|
2866
|
+
if (!instead || (flags & (O_ACCMODE2 | O_CREAT)) !== 0) return open(path, flags, mode);
|
|
2867
|
+
try {
|
|
2868
|
+
return open(path, flags, mode);
|
|
2869
|
+
} catch (e) {
|
|
2870
|
+
if (e?.errno !== wasiErrno("ENOENT")) throw e;
|
|
2871
|
+
return open(instead, flags, mode);
|
|
2872
|
+
}
|
|
2873
|
+
};
|
|
2874
|
+
}
|
|
2875
|
+
function cString(memory, at) {
|
|
2876
|
+
const bytes = new Uint8Array(memory.buffer, at);
|
|
2877
|
+
return new TextDecoder().decode(bytes.subarray(0, bytes.indexOf(0)));
|
|
2878
|
+
}
|
|
2879
|
+
function baseOf(Fs, dirfd) {
|
|
2880
|
+
return dirfd === AT_FDCWD ? Fs.cwd?.() ?? "/" : Fs.getStream?.(dirfd)?.path ?? "/";
|
|
2881
|
+
}
|
|
2882
|
+
function readonlyRefusal(Fs, memory, call2) {
|
|
2883
|
+
if (!(call2.amode & W_ACCESS)) return 0;
|
|
2884
|
+
try {
|
|
2885
|
+
const name2 = cString(memory, call2.path);
|
|
2886
|
+
const abs = name2.startsWith("/") ? name2 : `${baseOf(Fs, call2.dirfd)}/${name2}`;
|
|
2887
|
+
const follow2 = (call2.flags & AT_SYMLINK_NOFOLLOW) === 0;
|
|
2888
|
+
const { node } = Fs.lookupPath.call(Fs, abs, {
|
|
2889
|
+
follow: follow2
|
|
2890
|
+
});
|
|
2891
|
+
const bridge = node.live ? node.mount.opts.bridge : void 0;
|
|
2892
|
+
const stats = bridge;
|
|
2893
|
+
const stat = follow2 ? stats?.stat : stats?.lstat;
|
|
2894
|
+
return stat?.call(stats, liveNodePath(node)).readonly ? -wasiErrno("EROFS") : 0;
|
|
2895
|
+
} catch {
|
|
2896
|
+
return 0;
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
function kernelChecks(Fs, memory, call2) {
|
|
2900
|
+
const name2 = cString(memory, call2.path);
|
|
2901
|
+
const abs = name2.startsWith("/") ? name2 : `${baseOf(Fs, call2.dirfd)}/${name2}`;
|
|
2902
|
+
const lookupPath = Fs.lookupPath;
|
|
2903
|
+
const { node } = lookupPath.call(Fs, abs, { follow: (call2.flags & AT_SYMLINK_NOFOLLOW) === 0 });
|
|
2904
|
+
const bridge = node.live ? node.mount.opts.bridge : void 0;
|
|
2905
|
+
if (!bridge?.owners || !bridge.access) return 0;
|
|
2906
|
+
const kind = call2.flags & AT_EACCESS ? "eaccess" : "access";
|
|
2907
|
+
bridge.access(liveNodePath(node), call2.amode, kind, (call2.flags & AT_SYMLINK_NOFOLLOW) !== 0);
|
|
2908
|
+
return 0;
|
|
2909
|
+
}
|
|
2910
|
+
function kernelAccess(imports, fs, memory, glue) {
|
|
2911
|
+
wrapImport(imports, "faccessat", glue, (own) => (dirfd, path, amode, flags) => {
|
|
2912
|
+
const Fs = fs();
|
|
2913
|
+
const heap = memory();
|
|
2914
|
+
const call2 = { dirfd, path, amode: amode & 7, flags };
|
|
2915
|
+
const refused = Fs?.lookupPath && heap ? readonlyRefusal(Fs, heap, call2) : 0;
|
|
2916
|
+
if (refused !== 0) return refused;
|
|
2917
|
+
const rc = own(dirfd, path, amode, flags);
|
|
2918
|
+
if (rc !== 0 || !Fs?.lookupPath || !heap) return rc;
|
|
2919
|
+
try {
|
|
2920
|
+
return kernelChecks(Fs, heap, { dirfd, path, amode: amode & 7, flags });
|
|
2921
|
+
} catch (err) {
|
|
2922
|
+
return -errnoOf(err);
|
|
2923
|
+
}
|
|
2924
|
+
});
|
|
2925
|
+
}
|
|
2926
|
+
function kernelLink(imports, fs, memory, glue) {
|
|
2927
|
+
wrapImport(
|
|
2928
|
+
imports,
|
|
2929
|
+
"linkat",
|
|
2930
|
+
glue,
|
|
2931
|
+
(own) => (olddirfd, oldpath, newdirfd, newpath, flags) => {
|
|
2932
|
+
const Fs = fs();
|
|
2933
|
+
const heap = memory();
|
|
2934
|
+
if (!Fs?.lookupPath || !heap) return own(olddirfd, oldpath, newdirfd, newpath, flags);
|
|
2935
|
+
const at = (dirfd, ptr) => {
|
|
2936
|
+
const name2 = cString(heap, ptr);
|
|
2937
|
+
return name2.startsWith("/") ? name2 : `${baseOf(Fs, dirfd)}/${name2}`;
|
|
2938
|
+
};
|
|
2939
|
+
try {
|
|
2940
|
+
const from = at(olddirfd, oldpath);
|
|
2941
|
+
const to = at(newdirfd, newpath);
|
|
2942
|
+
const follow2 = (flags & AT_SYMLINK_FOLLOW) !== 0;
|
|
2943
|
+
if (linkLive(Fs, from, to, follow2)) return 0;
|
|
2944
|
+
} catch (err) {
|
|
2945
|
+
return -errnoOf(err);
|
|
2318
2946
|
}
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2947
|
+
return own(olddirfd, oldpath, newdirfd, newpath, flags);
|
|
2948
|
+
},
|
|
2949
|
+
true
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2952
|
+
function kernelChdir(Fs) {
|
|
2953
|
+
const { chdir, lookupPath, ErrnoError } = Fs;
|
|
2954
|
+
if (!chdir || !lookupPath || !ErrnoError) return;
|
|
2955
|
+
Fs.chdir = (path) => {
|
|
2956
|
+
const { node } = lookupPath.call(Fs, path, { follow: true });
|
|
2957
|
+
const directory = Fs.isDir?.(node.mode) === true;
|
|
2958
|
+
const bridge = node.live && directory ? node.mount.opts.bridge : void 0;
|
|
2959
|
+
try {
|
|
2960
|
+
bridge?.access?.(liveNodePath(node), X_ACCESS, "eaccess", false);
|
|
2961
|
+
} catch (err) {
|
|
2962
|
+
throw new ErrnoError(errnoOf(err));
|
|
2963
|
+
}
|
|
2964
|
+
chdir.call(Fs, path);
|
|
2965
|
+
};
|
|
2966
|
+
}
|
|
2967
|
+
function linuxDevices(Fs) {
|
|
2968
|
+
Fs.ignorePermissions = true;
|
|
2969
|
+
kernelChdir(Fs);
|
|
2970
|
+
const { chmod } = Fs;
|
|
2971
|
+
if (!chmod) return;
|
|
2972
|
+
for (const [path, mode] of DEVICE_MODES) {
|
|
2973
|
+
try {
|
|
2974
|
+
chmod.call(Fs, path, mode);
|
|
2975
|
+
} catch {
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
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_CREAT, field, pinnedRoot, rootKind, NAME, AT_FDCWD, AT_EACCESS, W_ACCESS, X_ACCESS, AT_SYMLINK_FOLLOW, DEVICE_MODES;
|
|
2980
|
+
var init_process_fds = __esm({
|
|
2981
|
+
"src/process/process-fds.ts"() {
|
|
2982
|
+
"use strict";
|
|
2983
|
+
init_dev_removal();
|
|
2984
|
+
init_loopback_names();
|
|
2985
|
+
init_live_vfs_fs();
|
|
2986
|
+
init_process_pty();
|
|
2987
|
+
init_wasi_errno();
|
|
2988
|
+
O_CLOEXEC = 524288;
|
|
2989
|
+
FD_CLOEXEC = 1;
|
|
2990
|
+
F_DUPFD = 0;
|
|
2991
|
+
F_GETFD = 1;
|
|
2992
|
+
F_SETFD = 2;
|
|
2993
|
+
F_GETFL = 3;
|
|
2994
|
+
F_DUPFD_CLOEXEC = 1030;
|
|
2995
|
+
tracked = /* @__PURE__ */ new WeakSet();
|
|
2996
|
+
IMPORT_NAMES = {
|
|
2997
|
+
fcntl: "__syscall_fcntl64",
|
|
2998
|
+
pipe2: "__syscall_pipe2",
|
|
2999
|
+
dup3: "__syscall_dup3",
|
|
3000
|
+
socket: "__syscall_socket",
|
|
3001
|
+
accept4: "__syscall_accept4",
|
|
3002
|
+
ioctl: "__syscall_ioctl",
|
|
3003
|
+
setitimer: "_setitimer_js"
|
|
3004
|
+
};
|
|
3005
|
+
EBADF = 8;
|
|
3006
|
+
AT_SYMLINK_NOFOLLOW = 256;
|
|
3007
|
+
EMSCRIPTEN_EPERM = 63;
|
|
3008
|
+
O_PATH2 = 2097152;
|
|
3009
|
+
LITERALS = {
|
|
3010
|
+
openat: "__syscall_openat",
|
|
3011
|
+
mkdirat: "__syscall_mkdirat",
|
|
3012
|
+
mknodat: "__syscall_mknodat",
|
|
3013
|
+
umask: "__syscall_umask",
|
|
3014
|
+
faccessat: "__syscall_faccessat",
|
|
3015
|
+
linkat: "__syscall_linkat",
|
|
3016
|
+
utimensat: "__syscall_utimensat",
|
|
3017
|
+
getppid: "slicc_getppid_js",
|
|
3018
|
+
resizeHeap: "emscripten_resize_heap",
|
|
3019
|
+
fdWrite: "fd_write",
|
|
3020
|
+
fdRead: "fd_read",
|
|
3021
|
+
sleepMs: "slicc_sleep_ms"
|
|
3022
|
+
};
|
|
3023
|
+
UTIME_NOW = 1073741823;
|
|
3024
|
+
UTIME_OMIT = 1073741822;
|
|
3025
|
+
PROT_WRITE = 2;
|
|
3026
|
+
MAP_PRIVATE = 2;
|
|
3027
|
+
MAP_TYPE = 15;
|
|
3028
|
+
O_WRONLY = 1;
|
|
3029
|
+
MAP_ALIGN = 65536;
|
|
3030
|
+
DIR_MODE = 16749;
|
|
3031
|
+
LINK_MODE = 41408;
|
|
3032
|
+
CHAR_DEVICE = 8630;
|
|
3033
|
+
O_ACCMODE2 = 3;
|
|
3034
|
+
O_CREAT = 64;
|
|
3035
|
+
field = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
3036
|
+
rootKind = () => globalThis.navigator?.storage ? "opfs" : "memory";
|
|
3037
|
+
NAME = /^[a-z_][a-z0-9_-]*$/i;
|
|
3038
|
+
AT_FDCWD = -100;
|
|
3039
|
+
AT_EACCESS = 512;
|
|
3040
|
+
W_ACCESS = 2;
|
|
3041
|
+
X_ACCESS = 1;
|
|
3042
|
+
AT_SYMLINK_FOLLOW = 1024;
|
|
3043
|
+
DEVICE_MODES = [
|
|
3044
|
+
["/", 493],
|
|
3045
|
+
["/dev", 493],
|
|
3046
|
+
["/dev/null", 438],
|
|
3047
|
+
["/dev/zero", 438],
|
|
3048
|
+
["/dev/full", 438],
|
|
3049
|
+
["/dev/random", 438],
|
|
3050
|
+
["/dev/urandom", 438],
|
|
3051
|
+
["/dev/tty", 438],
|
|
3052
|
+
["/dev/shm", 1023]
|
|
3053
|
+
];
|
|
3054
|
+
}
|
|
3055
|
+
});
|
|
3056
|
+
|
|
3057
|
+
// src/process/fd-metadata.ts
|
|
3058
|
+
function idOf2(value2) {
|
|
3059
|
+
return value2 === -1 || value2 === 4294967295 ? void 0 : value2 >>> 0;
|
|
3060
|
+
}
|
|
3061
|
+
function timeOf(value2) {
|
|
3062
|
+
return typeof value2 === "number" && Number.isFinite(value2) ? value2 : null;
|
|
3063
|
+
}
|
|
3064
|
+
function useKernelFdMetadata(Fs, sys, call2) {
|
|
3065
|
+
const { fdChown, fdChmod, fdUtimes } = sys;
|
|
3066
|
+
const meta = Fs;
|
|
3067
|
+
const kernelFd = (stream) => stream?.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
3068
|
+
const find = (match) => {
|
|
3069
|
+
for (const s of Fs.streams) {
|
|
3070
|
+
const kfd = s && match(s) ? kernelFd(s) : void 0;
|
|
3071
|
+
if (kfd !== void 0) return kfd;
|
|
3072
|
+
}
|
|
3073
|
+
return void 0;
|
|
3074
|
+
};
|
|
3075
|
+
const ofPath = (path, follow2) => {
|
|
3076
|
+
if (typeof path !== "string") return find((s) => s.node === path);
|
|
3077
|
+
const fd = follow2 ? fdOfPath(path, Fs.cwd()) : void 0;
|
|
3078
|
+
if (fd !== void 0) return kernelFd(Fs.getStream(fd));
|
|
3079
|
+
return find((s) => s.path === path);
|
|
3080
|
+
};
|
|
3081
|
+
const ofFd = (fd) => kernelFd(Fs.getStream(fd));
|
|
3082
|
+
const chownBy = (kfd, uid, gid) => call2(() => fdChown?.call(sys, kfd, idOf2(uid), idOf2(gid)));
|
|
3083
|
+
if (fdChown && meta.chown) {
|
|
3084
|
+
const chown = meta.chown.bind(Fs);
|
|
3085
|
+
meta.chown = (path, uid, gid, dontFollow) => {
|
|
3086
|
+
const kfd = ofPath(path, !dontFollow);
|
|
3087
|
+
if (kfd === void 0) return chown(path, uid, gid, dontFollow);
|
|
3088
|
+
chownBy(kfd, uid, gid);
|
|
3089
|
+
};
|
|
3090
|
+
}
|
|
3091
|
+
if (fdChown && meta.fchown) {
|
|
3092
|
+
const fchown = meta.fchown.bind(Fs);
|
|
3093
|
+
meta.fchown = (fd, uid, gid) => {
|
|
3094
|
+
const kfd = ofFd(fd);
|
|
3095
|
+
if (kfd === void 0) return fchown(fd, uid, gid);
|
|
3096
|
+
chownBy(kfd, uid, gid);
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
if (fdChmod && meta.chmod) {
|
|
3100
|
+
const chmod = meta.chmod.bind(Fs);
|
|
3101
|
+
meta.chmod = (path, mode, dontFollow) => {
|
|
3102
|
+
const kfd = ofPath(path, !dontFollow);
|
|
3103
|
+
if (kfd === void 0) return chmod(path, mode, dontFollow);
|
|
3104
|
+
call2(() => fdChmod.call(sys, kfd, mode & 4095));
|
|
3105
|
+
};
|
|
3106
|
+
}
|
|
3107
|
+
if (fdChmod && meta.fchmod) {
|
|
3108
|
+
const fchmod = meta.fchmod.bind(Fs);
|
|
3109
|
+
meta.fchmod = (fd, mode) => {
|
|
3110
|
+
const kfd = ofFd(fd);
|
|
3111
|
+
if (kfd === void 0) return fchmod(fd, mode);
|
|
3112
|
+
call2(() => fdChmod.call(sys, kfd, mode & 4095));
|
|
3113
|
+
};
|
|
3114
|
+
}
|
|
3115
|
+
if (fdUtimes && meta.utime) {
|
|
3116
|
+
const utime = meta.utime.bind(Fs);
|
|
3117
|
+
meta.utime = (path, atime, mtime) => {
|
|
3118
|
+
const kfd = ofPath(path, true);
|
|
3119
|
+
if (kfd === void 0) return utime(path, atime, mtime);
|
|
3120
|
+
const now = meta.sliccTouch === true;
|
|
3121
|
+
call2(() => fdUtimes.call(sys, kfd, timeOf(atime), timeOf(mtime), now));
|
|
3122
|
+
};
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
var init_fd_metadata = __esm({
|
|
3126
|
+
"src/process/fd-metadata.ts"() {
|
|
3127
|
+
"use strict";
|
|
3128
|
+
init_process_fds();
|
|
3129
|
+
}
|
|
3130
|
+
});
|
|
3131
|
+
|
|
3132
|
+
// src/process/kernel-streams.ts
|
|
3133
|
+
function isPtyPath(path) {
|
|
3134
|
+
return PTY_PATH.test(path);
|
|
3135
|
+
}
|
|
3136
|
+
function ptyStat(path) {
|
|
3137
|
+
const n = PTY_PATH.exec(path)?.[1];
|
|
3138
|
+
const now = /* @__PURE__ */ new Date();
|
|
3139
|
+
return {
|
|
3140
|
+
dev: 22,
|
|
3141
|
+
ino: n === void 0 ? 2 : 3 + Number(n),
|
|
3142
|
+
mode: n === void 0 ? 8630 : 8592,
|
|
3143
|
+
nlink: 1,
|
|
3144
|
+
uid: 1e3,
|
|
3145
|
+
gid: 1e3,
|
|
3146
|
+
rdev: n === void 0 ? 5 << 8 | 2 : 136 << 8 | Number(n),
|
|
3147
|
+
size: 0,
|
|
3148
|
+
blksize: 4096,
|
|
3149
|
+
blocks: 0,
|
|
3150
|
+
atime: now,
|
|
3151
|
+
mtime: now,
|
|
3152
|
+
ctime: now
|
|
3153
|
+
};
|
|
3154
|
+
}
|
|
3155
|
+
function sealedStat(minor = 250) {
|
|
3156
|
+
const now = /* @__PURE__ */ new Date();
|
|
3157
|
+
return {
|
|
3158
|
+
dev: 22,
|
|
3159
|
+
ino: minor === 251 ? 2 : 1,
|
|
3160
|
+
mode: 8630,
|
|
3161
|
+
nlink: 1,
|
|
3162
|
+
uid: 0,
|
|
3163
|
+
gid: 0,
|
|
3164
|
+
rdev: 10 << 8 | minor,
|
|
3165
|
+
size: 0,
|
|
3166
|
+
blksize: 4096,
|
|
3167
|
+
blocks: 0,
|
|
3168
|
+
atime: now,
|
|
3169
|
+
mtime: now,
|
|
3170
|
+
ctime: now
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
function nonblocking(stream) {
|
|
3174
|
+
return (stream.flags & O_NONBLOCK) !== 0 ? { nonblock: true } : void 0;
|
|
3175
|
+
}
|
|
3176
|
+
function datesOf(real) {
|
|
3177
|
+
const dates = {};
|
|
3178
|
+
for (const [key, value2] of Object.entries(real ?? {}))
|
|
3179
|
+
if (/^[amc]time$/.test(key) && (typeof value2 === "string" || typeof value2 === "number"))
|
|
3180
|
+
dates[key] = new Date(value2);
|
|
3181
|
+
return dates;
|
|
3182
|
+
}
|
|
3183
|
+
var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, SEALED_PATH, STRERROR, CLIPBOARD_PATH, O_CREAT2, O_EXCL, O_NOCTTY, O_TRUNC2, O_DIRECTORY, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
|
|
3184
|
+
var init_kernel_streams = __esm({
|
|
3185
|
+
"src/process/kernel-streams.ts"() {
|
|
3186
|
+
"use strict";
|
|
3187
|
+
init_fd_metadata();
|
|
3188
|
+
init_wasi_errno();
|
|
3189
|
+
POLLIN = 1;
|
|
3190
|
+
POLLOUT = 4;
|
|
3191
|
+
POLLERR = 8;
|
|
3192
|
+
POLLHUP = 16;
|
|
3193
|
+
POLLRDNORM = 64;
|
|
3194
|
+
POLLWRNORM = 256;
|
|
3195
|
+
TCSETSF = 21508;
|
|
3196
|
+
O_NONBLOCK = 2048;
|
|
3197
|
+
SOCKET_MODE = 49663;
|
|
3198
|
+
PTY_PATH = /^\/dev\/(?:ptmx|pts\/(\d+))$/;
|
|
3199
|
+
TTY_PATH = /^\/dev\/tty\d+$/;
|
|
3200
|
+
TTY_NAME = /^tty\d+$/;
|
|
3201
|
+
SEALED_PATH = "/dev/sealed";
|
|
3202
|
+
STRERROR = {
|
|
3203
|
+
EACCES: "Permission denied",
|
|
3204
|
+
EIO: "I/O error",
|
|
3205
|
+
ENOTSUP: "Not supported",
|
|
3206
|
+
EOPNOTSUPP: "Not supported",
|
|
3207
|
+
EFBIG: "File too large",
|
|
3208
|
+
EILSEQ: "Illegal byte sequence",
|
|
3209
|
+
EINTR: "Interrupted system call"
|
|
3210
|
+
};
|
|
3211
|
+
CLIPBOARD_PATH = "/dev/clipboard";
|
|
3212
|
+
O_CREAT2 = 64;
|
|
3213
|
+
O_EXCL = 128;
|
|
3214
|
+
O_NOCTTY = 256;
|
|
3215
|
+
O_TRUNC2 = 512;
|
|
3216
|
+
O_DIRECTORY = 65536;
|
|
3217
|
+
KILLED_BY_SIGPIPE = 128 + 13;
|
|
3218
|
+
ProcessExit = class extends Error {
|
|
3219
|
+
status;
|
|
3220
|
+
constructor(status2) {
|
|
3221
|
+
super(`exit ${status2}`);
|
|
3222
|
+
this.status = status2;
|
|
2354
3223
|
}
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
return 0;
|
|
2362
|
-
}),
|
|
2363
|
-
ioctl_tiocgwinsz: () => this.call(() => this.sys.winsize?.(kfd) ?? [24, 80]),
|
|
2364
|
-
fsync: () => {
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
};
|
|
3224
|
+
};
|
|
3225
|
+
SyscallError = class extends Error {
|
|
3226
|
+
code;
|
|
3227
|
+
constructor(code2) {
|
|
3228
|
+
super(code2);
|
|
3229
|
+
this.code = code2;
|
|
2368
3230
|
}
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
3231
|
+
};
|
|
3232
|
+
KernelStreams = class {
|
|
3233
|
+
refs = /* @__PURE__ */ new Map();
|
|
3234
|
+
socketRoot;
|
|
3235
|
+
sockets = 0;
|
|
3236
|
+
descriptions = /* @__PURE__ */ new Map();
|
|
3237
|
+
described = 0;
|
|
3238
|
+
Fs;
|
|
3239
|
+
sys;
|
|
3240
|
+
options;
|
|
3241
|
+
constructor(Fs, sys, options = {}) {
|
|
3242
|
+
this.Fs = Fs;
|
|
3243
|
+
this.sys = sys;
|
|
3244
|
+
this.options = options;
|
|
3245
|
+
}
|
|
3246
|
+
attach(stream, kfd, terminal) {
|
|
3247
|
+
this.refs.set(kfd, (this.refs.get(kfd) ?? 0) + 1);
|
|
3248
|
+
stream.sliccKernelFd = kfd;
|
|
3249
|
+
stream.stream_ops = this.ops(kfd, stream.stream_ops);
|
|
3250
|
+
if (terminal ?? this.sys.isatty?.(kfd) ?? false) stream.tty = this.ttyOps(kfd);
|
|
3251
|
+
else delete stream.tty;
|
|
3252
|
+
}
|
|
3253
|
+
attachSocket(stream, kfd) {
|
|
3254
|
+
this.attach(stream, kfd, false);
|
|
3255
|
+
stream.sliccKernelSocket = true;
|
|
3256
|
+
}
|
|
3257
|
+
socketStream(flags) {
|
|
3258
|
+
const fs = this.Fs;
|
|
3259
|
+
if (!fs.mount || !fs.createNode || !fs.createStream) {
|
|
3260
|
+
const stream = this.Fs.open("/dev/null", 2);
|
|
3261
|
+
stream.flags = flags;
|
|
3262
|
+
return stream;
|
|
3263
|
+
}
|
|
3264
|
+
const createNode = fs.createNode;
|
|
3265
|
+
this.socketRoot ??= fs.mount({ mount: () => createNode(null, "/", 16895, 0) }, {}, null);
|
|
3266
|
+
const ino = ++this.sockets;
|
|
3267
|
+
const node = fs.createNode(this.socketRoot, `socket:${ino}`, SOCKET_MODE, 0);
|
|
3268
|
+
const now = /* @__PURE__ */ new Date();
|
|
3269
|
+
const stat = { dev: 0, ino, mode: SOCKET_MODE, nlink: 1, uid: 0, gid: 0, rdev: 0, size: 0 };
|
|
3270
|
+
const times = { atime: now, mtime: now, ctime: now, blksize: 4096, blocks: 0 };
|
|
3271
|
+
node.node_ops = { getattr: () => ({ ...stat, ...times }) };
|
|
3272
|
+
return fs.createStream({ node, flags, seekable: false, position: 0, stream_ops: {} });
|
|
3273
|
+
}
|
|
3274
|
+
nameTerminal(stream) {
|
|
3275
|
+
const kfd = stream.sliccKernelFd;
|
|
3276
|
+
if (!stream.tty || kfd === void 0) return;
|
|
3277
|
+
const name2 = this.sys.ttyName?.(kfd);
|
|
3278
|
+
if (name2) this.nameStream(stream, name2);
|
|
3279
|
+
}
|
|
3280
|
+
nameStream(stream, name2) {
|
|
3281
|
+
stream.path = name2;
|
|
3282
|
+
this.ttyNode(name2);
|
|
3283
|
+
if (typeof this.Fs.stat !== "function") return;
|
|
3284
|
+
stream.stream_ops = { ...stream.stream_ops, getattr: () => this.Fs.stat?.(name2) ?? {} };
|
|
3285
|
+
}
|
|
3286
|
+
nameDevice(stream, kind) {
|
|
3287
|
+
this.nameStream(stream, kind === "sealed" ? SEALED_PATH : CLIPBOARD_PATH);
|
|
3288
|
+
}
|
|
3289
|
+
listSealed() {
|
|
3290
|
+
const fs = this.Fs;
|
|
3291
|
+
const { analyzePath, mkdev, makedev, registerDevice } = fs;
|
|
3292
|
+
if (!analyzePath || !mkdev || !makedev) return;
|
|
3293
|
+
const nodes = [
|
|
3294
|
+
[SEALED_PATH, 250, this.sys.openSealed],
|
|
3295
|
+
[CLIPBOARD_PATH, 251, this.sys.openClipboard]
|
|
3296
|
+
];
|
|
3297
|
+
for (const [path, minor, opener] of nodes) {
|
|
3298
|
+
if (!opener) continue;
|
|
3299
|
+
const dev = makedev.call(fs, 10, minor);
|
|
3300
|
+
registerDevice?.call(fs, dev, {
|
|
3301
|
+
open: (stream) => this.openNode(stream, path, opener)
|
|
3302
|
+
});
|
|
3303
|
+
if (analyzePath.call(fs, path).exists) continue;
|
|
3304
|
+
try {
|
|
3305
|
+
const node = mkdev.call(fs, path, dev);
|
|
3306
|
+
if (typeof node === "object" && node !== null) {
|
|
3307
|
+
const made = node;
|
|
3308
|
+
made.node_ops = { ...made.node_ops, getattr: () => sealedStat(minor) };
|
|
3309
|
+
}
|
|
3310
|
+
} catch {
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
openNode(stream, path, opener) {
|
|
3315
|
+
let kfd;
|
|
3316
|
+
try {
|
|
3317
|
+
kfd = this.call(() => opener.call(this.sys, stream.flags & 3));
|
|
3318
|
+
} catch (e) {
|
|
3319
|
+
this.Fs.closeStream(stream.fd);
|
|
3320
|
+
throw e;
|
|
3321
|
+
}
|
|
3322
|
+
this.attach(stream, kfd, false);
|
|
3323
|
+
this.nameStream(stream, path);
|
|
3324
|
+
if (path === CLIPBOARD_PATH) this.reportClose(kfd);
|
|
3325
|
+
}
|
|
3326
|
+
reporting = /* @__PURE__ */ new Set();
|
|
3327
|
+
reportClose(kfd) {
|
|
3328
|
+
this.reporting.add(kfd);
|
|
3329
|
+
}
|
|
3330
|
+
quitting = false;
|
|
3331
|
+
atExit = false;
|
|
3332
|
+
failedAtExit = false;
|
|
3333
|
+
committed = /* @__PURE__ */ new Set();
|
|
3334
|
+
exiting() {
|
|
3335
|
+
this.atExit = true;
|
|
3336
|
+
return () => {
|
|
3337
|
+
this.atExit = false;
|
|
3338
|
+
};
|
|
3339
|
+
}
|
|
3340
|
+
commitStdout() {
|
|
3341
|
+
const kfd = this.Fs.getStream(1)?.sliccKernelFd;
|
|
3342
|
+
if (kfd === void 0 || !this.reporting.delete(kfd)) return;
|
|
3343
|
+
this.committed.add(kfd);
|
|
3344
|
+
try {
|
|
3345
|
+
this.sys.close(kfd);
|
|
3346
|
+
} catch (e) {
|
|
3347
|
+
if (e instanceof SyscallError) this.stdoutFailed(e.code);
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
exitStatus(status2) {
|
|
3351
|
+
return this.failedAtExit && status2 === 0 ? 1 : status2;
|
|
3352
|
+
}
|
|
3353
|
+
reportedClose(stream, kfd) {
|
|
3354
|
+
try {
|
|
3355
|
+
this.sys.close(kfd);
|
|
3356
|
+
} catch (e) {
|
|
3357
|
+
if (this.quitting && stream.fd === 1 && e instanceof SyscallError) this.stdoutFailed(e.code);
|
|
3358
|
+
this.call(() => {
|
|
3359
|
+
throw e;
|
|
3360
|
+
});
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
stdoutFailed(code2) {
|
|
3364
|
+
this.failedAtExit = true;
|
|
3365
|
+
const stderr = this.Fs.getStream(2)?.sliccKernelFd;
|
|
3366
|
+
if (stderr === void 0) return;
|
|
3367
|
+
const line = `${this.options.program ?? "program"}: write error: ${STRERROR[code2] ?? code2}
|
|
3368
|
+
`;
|
|
3369
|
+
try {
|
|
3370
|
+
this.sys.write(stderr, new TextEncoder().encode(line));
|
|
3371
|
+
} catch {
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
creatingTerminal = false;
|
|
3375
|
+
useTerminalNodes() {
|
|
3376
|
+
const fs = this.Fs;
|
|
3377
|
+
const { lookupNode, readdir, getPath, mkdev, makedev } = fs;
|
|
3378
|
+
const ttyNames = this.sys.ttyNames?.bind(this.sys);
|
|
3379
|
+
if (!lookupNode || !readdir || !getPath || !mkdev || !makedev || !ttyNames) return;
|
|
3380
|
+
fs.lookupNode = (parent, name2) => {
|
|
3381
|
+
try {
|
|
3382
|
+
return lookupNode.call(fs, parent, name2);
|
|
3383
|
+
} catch (e) {
|
|
3384
|
+
const path = `/dev/${name2}`;
|
|
3385
|
+
if (this.creatingTerminal || !TTY_NAME.test(name2) || getPath.call(fs, parent) !== "/dev")
|
|
3386
|
+
throw e;
|
|
3387
|
+
if (!ttyNames().includes(path)) throw e;
|
|
3388
|
+
this.creatingTerminal = true;
|
|
3389
|
+
try {
|
|
3390
|
+
mkdev.call(fs, path, makedev.call(fs, 6, 0));
|
|
3391
|
+
} finally {
|
|
3392
|
+
this.creatingTerminal = false;
|
|
3393
|
+
}
|
|
3394
|
+
return lookupNode.call(fs, parent, name2);
|
|
3395
|
+
}
|
|
3396
|
+
};
|
|
3397
|
+
fs.readdir = (path) => {
|
|
3398
|
+
const names = readdir.call(fs, path);
|
|
3399
|
+
if (path.replace(/\/+$/, "") !== "/dev") return names;
|
|
3400
|
+
const missing2 = ttyNames().map((tty) => tty.slice("/dev/".length)).filter((name2) => TTY_NAME.test(name2) && !names.includes(name2));
|
|
3401
|
+
return [...names, ...missing2];
|
|
3402
|
+
};
|
|
3403
|
+
}
|
|
3404
|
+
ttyNode(name2) {
|
|
3405
|
+
const { analyzePath, mkdev, makedev } = this.Fs;
|
|
3406
|
+
if (!TTY_PATH.test(name2) || !analyzePath || !mkdev || !makedev) return;
|
|
3407
|
+
if (!analyzePath.call(this.Fs, name2).exists)
|
|
3408
|
+
mkdev.call(this.Fs, name2, makedev.call(this.Fs, 6, 0));
|
|
3409
|
+
}
|
|
3410
|
+
ttyOps(kfd) {
|
|
3411
|
+
return {
|
|
3412
|
+
ops: {
|
|
3413
|
+
ioctl_tcgets: () => this.call(() => this.sys.tcgets?.(kfd)),
|
|
3414
|
+
ioctl_tcsets: (_tty, op, termios) => this.call(() => {
|
|
3415
|
+
this.sys.tcsets?.(kfd, termios, op === TCSETSF);
|
|
3416
|
+
return 0;
|
|
3417
|
+
}),
|
|
3418
|
+
ioctl_tiocgwinsz: () => this.call(() => this.sys.winsize?.(kfd) ?? [24, 80]),
|
|
3419
|
+
fsync: () => {
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
};
|
|
3423
|
+
}
|
|
3424
|
+
attachFile(stream, kfd) {
|
|
3425
|
+
this.attach(stream, kfd, false);
|
|
3426
|
+
stream.sliccKernelFile = true;
|
|
3427
|
+
stream.stream_ops = {
|
|
3428
|
+
...stream.stream_ops,
|
|
3429
|
+
llseek: (_s, offset, whence) => this.call(() => this.sys.seek(kfd, offset, whence)),
|
|
3430
|
+
fsync: () => this.call(() => {
|
|
3431
|
+
this.sys.flush(kfd);
|
|
3432
|
+
return 0;
|
|
3433
|
+
})
|
|
3434
|
+
};
|
|
2380
3435
|
}
|
|
2381
3436
|
sizeFromKernel(stream, kfd) {
|
|
2382
|
-
const { size } = this.sys;
|
|
3437
|
+
const { size, fdStat: fdStat2 } = this.sys;
|
|
2383
3438
|
if (!size) return;
|
|
2384
3439
|
const node = stream.node;
|
|
2385
|
-
this.describe(stream, `${stream.path ?? ""}:${++this.described}`, () =>
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
3440
|
+
this.describe(stream, `${stream.path ?? ""}:${++this.described}`, () => {
|
|
3441
|
+
const base = node.node_ops?.getattr?.(node);
|
|
3442
|
+
const live = this.call(() => size.call(this.sys, kfd));
|
|
3443
|
+
const real = fdStat2 && this.call(() => fdStat2.call(this.sys, kfd));
|
|
3444
|
+
return { ...base, ...real, ...datesOf(real), size: live };
|
|
3445
|
+
});
|
|
2389
3446
|
}
|
|
2390
3447
|
describe(stream, name2, getattr) {
|
|
2391
3448
|
if (this.descriptions.size === 0) this.useDescriptions();
|
|
@@ -2404,6 +3461,9 @@ var init_kernel_streams = __esm({
|
|
|
2404
3461
|
};
|
|
2405
3462
|
}
|
|
2406
3463
|
}
|
|
3464
|
+
useKernelFdMetadata() {
|
|
3465
|
+
useKernelFdMetadata(this.Fs, this.sys, this.call.bind(this));
|
|
3466
|
+
}
|
|
2407
3467
|
useControllingTerminal() {
|
|
2408
3468
|
if (typeof this.Fs.open !== "function") return;
|
|
2409
3469
|
this.usePtyPaths();
|
|
@@ -2457,7 +3517,7 @@ var init_kernel_streams = __esm({
|
|
|
2457
3517
|
}
|
|
2458
3518
|
}
|
|
2459
3519
|
refuseExclusiveLink(path, flags) {
|
|
2460
|
-
if ((flags & (
|
|
3520
|
+
if ((flags & (O_CREAT2 | O_EXCL)) !== (O_CREAT2 | O_EXCL)) return;
|
|
2461
3521
|
let mode = 0;
|
|
2462
3522
|
try {
|
|
2463
3523
|
mode = this.Fs.stat?.(path, true)?.mode ?? 0;
|
|
@@ -2484,15 +3544,22 @@ var init_kernel_streams = __esm({
|
|
|
2484
3544
|
openClipboard(open, path, flags, mode) {
|
|
2485
3545
|
const { openClipboard } = this.sys;
|
|
2486
3546
|
if (path !== CLIPBOARD_PATH || !openClipboard) return void 0;
|
|
3547
|
+
if (flags & O_DIRECTORY) throw new this.Fs.ErrnoError(wasiErrno("ENOTDIR"));
|
|
2487
3548
|
const kfd = this.call(() => openClipboard.call(this.sys, flags & 3));
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
3549
|
+
try {
|
|
3550
|
+
const stream = this.vessel(open, kfd, { path, flags, mode }, false);
|
|
3551
|
+
this.reportClose(kfd);
|
|
3552
|
+
return stream;
|
|
3553
|
+
} catch (e) {
|
|
3554
|
+
this.sys.clipboardAbort?.(kfd);
|
|
3555
|
+
this.sys.close(kfd);
|
|
3556
|
+
throw e;
|
|
3557
|
+
}
|
|
2491
3558
|
}
|
|
2492
3559
|
vessel(open, kfd, at, terminal) {
|
|
2493
3560
|
let stream;
|
|
2494
3561
|
try {
|
|
2495
|
-
stream = open("/dev/null", at.flags & ~(
|
|
3562
|
+
stream = open("/dev/null", at.flags & ~(O_CREAT2 | O_EXCL | O_TRUNC2), at.mode);
|
|
2496
3563
|
} catch (e) {
|
|
2497
3564
|
this.sys.close(kfd);
|
|
2498
3565
|
throw e;
|
|
@@ -2620,869 +3687,64 @@ var init_kernel_streams = __esm({
|
|
|
2620
3687
|
return {
|
|
2621
3688
|
...base,
|
|
2622
3689
|
llseek: () => this.call(() => {
|
|
2623
|
-
throw new SyscallError("ESPIPE");
|
|
2624
|
-
}),
|
|
2625
|
-
read: (s, buffer, offset, length) => this.call(() => {
|
|
2626
|
-
const bytes = this.restarting(() => this.sys.read(kfd, length, nonblocking(s)));
|
|
2627
|
-
buffer.set(bytes, offset);
|
|
2628
|
-
return bytes.length;
|
|
2629
|
-
}),
|
|
2630
|
-
write: (s, buffer, offset, length) => {
|
|
2631
|
-
try {
|
|
2632
|
-
const bytes = buffer.slice(offset, offset + length);
|
|
2633
|
-
return this.restarting(() => this.sys.write(kfd, bytes, nonblocking(s)));
|
|
2634
|
-
} catch (e) {
|
|
2635
|
-
if (e instanceof SyscallError && e.code === "EPIPE" && !this.options.sigpipe?.()) {
|
|
2636
|
-
throw new ProcessExit(KILLED_BY_SIGPIPE);
|
|
2637
|
-
}
|
|
2638
|
-
return this.call(() => {
|
|
2639
|
-
throw e;
|
|
2640
|
-
});
|
|
2641
|
-
}
|
|
2642
|
-
},
|
|
2643
|
-
fsync: () => 0,
|
|
2644
|
-
poll: () => {
|
|
2645
|
-
const state = this.call(() => this.sys.poll(kfd));
|
|
2646
|
-
let mask = 0;
|
|
2647
|
-
if (state.readable) mask |= POLLIN | POLLRDNORM;
|
|
2648
|
-
if (state.writable) mask |= POLLOUT | POLLWRNORM;
|
|
2649
|
-
if (state.hangup) mask |= state.readable ? POLLHUP : POLLERR;
|
|
2650
|
-
return mask;
|
|
2651
|
-
},
|
|
2652
|
-
dup: (stream) => {
|
|
2653
|
-
base.dup?.(stream);
|
|
2654
|
-
this.refs.set(kfd, (this.refs.get(kfd) ?? 0) + 1);
|
|
2655
|
-
},
|
|
2656
|
-
close: (stream) => {
|
|
2657
|
-
if (this.atExit && stream.fd === 2 && this.reporting.size > 0) this.commitStdout();
|
|
2658
|
-
try {
|
|
2659
|
-
base.close?.(stream);
|
|
2660
|
-
} catch {
|
|
2661
|
-
}
|
|
2662
|
-
const left = (this.refs.get(kfd) ?? 1) - 1;
|
|
2663
|
-
if (left > 0) {
|
|
2664
|
-
this.refs.set(kfd, left);
|
|
2665
|
-
return;
|
|
2666
|
-
}
|
|
2667
|
-
this.refs.delete(kfd);
|
|
2668
|
-
if (this.committed.size > 0 && this.committed.delete(kfd)) return;
|
|
2669
|
-
if (this.reporting.size > 0 && this.reporting.delete(kfd)) {
|
|
2670
|
-
this.reportedClose(stream, kfd);
|
|
2671
|
-
return;
|
|
2672
|
-
}
|
|
2673
|
-
try {
|
|
2674
|
-
this.sys.close(kfd);
|
|
2675
|
-
} catch {
|
|
2676
|
-
}
|
|
2677
|
-
}
|
|
2678
|
-
};
|
|
2679
|
-
}
|
|
2680
|
-
};
|
|
2681
|
-
}
|
|
2682
|
-
});
|
|
2683
|
-
|
|
2684
|
-
// src/process/process-pty.ts
|
|
2685
|
-
function failed(e) {
|
|
2686
|
-
const code2 = e?.code;
|
|
2687
|
-
if (typeof code2 === "string") return -wasiErrno(code2);
|
|
2688
|
-
throw e;
|
|
2689
|
-
}
|
|
2690
|
-
function ptyIoctl(ioctl, deps) {
|
|
2691
|
-
return (fd, op, varargs) => {
|
|
2692
|
-
const request = op >>> 0;
|
|
2693
|
-
if (request !== TIOCGPTN && request !== TIOCSPTLCK && request !== TIOCSCTTY && request !== TIOCSWINSZ && request !== TIOCPKT) {
|
|
2694
|
-
return ioctl(fd, op, varargs);
|
|
2695
|
-
}
|
|
2696
|
-
const stream = deps.fs()?.getStream(fd);
|
|
2697
|
-
const kfd = stream?.sliccKernelFd;
|
|
2698
|
-
if (kfd === void 0) return ioctl(fd, op, varargs);
|
|
2699
|
-
const heap = deps.heap();
|
|
2700
|
-
if (!heap) return -wasiErrno("EFAULT");
|
|
2701
|
-
const argp = (heap[varargs >> 2] ?? 0) >>> 0;
|
|
2702
|
-
try {
|
|
2703
|
-
return answer(request, kfd, argp, heap, deps.kernel);
|
|
2704
|
-
} catch (e) {
|
|
2705
|
-
return failed(e);
|
|
2706
|
-
}
|
|
2707
|
-
};
|
|
2708
|
-
}
|
|
2709
|
-
function answer(request, kfd, argp, heap, kernel) {
|
|
2710
|
-
switch (request) {
|
|
2711
|
-
case TIOCGPTN:
|
|
2712
|
-
heap[argp >> 2] = kernel.ptyNumber(kfd);
|
|
2713
|
-
return 0;
|
|
2714
|
-
case TIOCSPTLCK:
|
|
2715
|
-
kernel.ptyLock(kfd, (heap[argp >> 2] ?? 0) !== 0);
|
|
2716
|
-
return 0;
|
|
2717
|
-
case TIOCSCTTY:
|
|
2718
|
-
kernel.setControllingTerminal(kfd);
|
|
2719
|
-
return 0;
|
|
2720
|
-
case TIOCPKT:
|
|
2721
|
-
kernel.setPacketMode(kfd, (heap[argp >> 2] ?? 0) !== 0);
|
|
2722
|
-
return 0;
|
|
2723
|
-
default: {
|
|
2724
|
-
const word = heap[argp >> 2] ?? 0;
|
|
2725
|
-
kernel.setWinsize(kfd, word & 65535, word >>> 16 & 65535);
|
|
2726
|
-
return 0;
|
|
2727
|
-
}
|
|
2728
|
-
}
|
|
2729
|
-
}
|
|
2730
|
-
var TIOCGPTN, TIOCSPTLCK, TIOCSCTTY, TIOCSWINSZ, TIOCPKT;
|
|
2731
|
-
var init_process_pty = __esm({
|
|
2732
|
-
"src/process/process-pty.ts"() {
|
|
2733
|
-
"use strict";
|
|
2734
|
-
init_wasi_errno();
|
|
2735
|
-
TIOCGPTN = 2147767344;
|
|
2736
|
-
TIOCSPTLCK = 1074025521;
|
|
2737
|
-
TIOCSCTTY = 21518;
|
|
2738
|
-
TIOCSWINSZ = 21524;
|
|
2739
|
-
TIOCPKT = 21536;
|
|
2740
|
-
}
|
|
2741
|
-
});
|
|
2742
|
-
|
|
2743
|
-
// src/process/process-fds.ts
|
|
2744
|
-
function closesOnExec(stream) {
|
|
2745
|
-
return stream.sliccCloexec === true;
|
|
2746
|
-
}
|
|
2747
|
-
function setCloseOnExec(stream, on) {
|
|
2748
|
-
if (on) stream.sliccCloexec = true;
|
|
2749
|
-
else delete stream.sliccCloexec;
|
|
2750
|
-
}
|
|
2751
|
-
function trackCloseOnExec(Fs) {
|
|
2752
|
-
if (tracked.has(Fs)) return;
|
|
2753
|
-
tracked.add(Fs);
|
|
2754
|
-
if (typeof Fs.dupStream === "function") {
|
|
2755
|
-
const dupStream = Fs.dupStream.bind(Fs);
|
|
2756
|
-
Fs.dupStream = (stream, fd) => {
|
|
2757
|
-
const copy2 = dupStream(stream, fd);
|
|
2758
|
-
setCloseOnExec(copy2, false);
|
|
2759
|
-
return copy2;
|
|
2760
|
-
};
|
|
2761
|
-
}
|
|
2762
|
-
if (typeof Fs.open === "function") {
|
|
2763
|
-
const open = Fs.open.bind(Fs);
|
|
2764
|
-
Fs.open = (path, flags, mode) => {
|
|
2765
|
-
const cloexec = typeof flags === "number" && (flags & O_CLOEXEC) !== 0;
|
|
2766
|
-
const stream = open(path, cloexec ? flags & ~O_CLOEXEC : flags, mode);
|
|
2767
|
-
setCloseOnExec(stream, cloexec);
|
|
2768
|
-
return stream;
|
|
2769
|
-
};
|
|
2770
|
-
}
|
|
2771
|
-
}
|
|
2772
|
-
function marker(deps) {
|
|
2773
|
-
return (fd, on) => {
|
|
2774
|
-
const stream = deps.fs()?.getStream(fd);
|
|
2775
|
-
if (stream) setCloseOnExec(stream, on);
|
|
2776
|
-
};
|
|
2777
|
-
}
|
|
2778
|
-
function cloexecFcntl(fcntl, deps) {
|
|
2779
|
-
const mark = marker(deps);
|
|
2780
|
-
return (fd, cmd, varargs) => {
|
|
2781
|
-
if (cmd === F_DUPFD_CLOEXEC) {
|
|
2782
|
-
const copy2 = fcntl(fd, F_DUPFD, varargs);
|
|
2783
|
-
if (copy2 >= 0) mark(copy2, true);
|
|
2784
|
-
return copy2;
|
|
2785
|
-
}
|
|
2786
|
-
if (cmd === F_GETFL) {
|
|
2787
|
-
const flags = fcntl(fd, cmd, varargs);
|
|
2788
|
-
return flags < 0 ? flags : flags & ~O_CLOEXEC;
|
|
2789
|
-
}
|
|
2790
|
-
if (cmd !== F_GETFD && cmd !== F_SETFD) return fcntl(fd, cmd, varargs);
|
|
2791
|
-
const stream = deps.fs()?.getStream(fd);
|
|
2792
|
-
if (!stream) return -wasiErrno("EBADF");
|
|
2793
|
-
if (cmd === F_GETFD) return closesOnExec(stream) ? FD_CLOEXEC : 0;
|
|
2794
|
-
const arg = deps.heap()?.[varargs >> 2];
|
|
2795
|
-
if (arg === void 0) return -wasiErrno("EINVAL");
|
|
2796
|
-
setCloseOnExec(stream, (arg & FD_CLOEXEC) !== 0);
|
|
2797
|
-
return 0;
|
|
2798
|
-
};
|
|
2799
|
-
}
|
|
2800
|
-
function cloexecPipe2(pipe2, deps) {
|
|
2801
|
-
const mark = marker(deps);
|
|
2802
|
-
return (fdPtr, flags) => {
|
|
2803
|
-
const r = pipe2(fdPtr, flags & ~O_CLOEXEC);
|
|
2804
|
-
const heap = deps.heap();
|
|
2805
|
-
if (r === 0 && flags & O_CLOEXEC && heap) {
|
|
2806
|
-
mark(heap[fdPtr >> 2], true);
|
|
2807
|
-
mark(heap[(fdPtr >> 2) + 1], true);
|
|
2808
|
-
}
|
|
2809
|
-
return r;
|
|
2810
|
-
};
|
|
2811
|
-
}
|
|
2812
|
-
function quietTarget(dup3, deps) {
|
|
2813
|
-
return (fd = -1, newfd = -1, flags = 0, ...rest2) => {
|
|
2814
|
-
const Fs = deps.fs();
|
|
2815
|
-
const target = fd === newfd || flags !== 0 ? void 0 : Fs?.getStream(newfd);
|
|
2816
|
-
if (target && Fs?.getStream(fd)) {
|
|
2817
|
-
try {
|
|
2818
|
-
Fs.close?.(target);
|
|
2819
|
-
} catch {
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
return dup3(fd, newfd, flags, ...rest2);
|
|
2823
|
-
};
|
|
2824
|
-
}
|
|
2825
|
-
function cloexecByFlag(syscall, flagArg, deps) {
|
|
2826
|
-
const mark = marker(deps);
|
|
2827
|
-
return (...args) => {
|
|
2828
|
-
const cloexec = ((args[flagArg] ?? 0) & O_CLOEXEC) !== 0;
|
|
2829
|
-
if (cloexec) args[flagArg] = args[flagArg] & ~O_CLOEXEC;
|
|
2830
|
-
const fd = syscall(...args);
|
|
2831
|
-
if (fd >= 0) mark(fd, cloexec);
|
|
2832
|
-
return fd;
|
|
2833
|
-
};
|
|
2834
|
-
}
|
|
2835
|
-
function wrapperFactories(deps) {
|
|
2836
|
-
const { pty, timer } = deps;
|
|
2837
|
-
return {
|
|
2838
|
-
...timer ? { setitimer: (f) => kernelTimer(f, timer) } : {},
|
|
2839
|
-
fcntl: (f) => cloexecFcntl(f, deps),
|
|
2840
|
-
pipe2: (f) => cloexecPipe2(f, deps),
|
|
2841
|
-
dup3: (f) => cloexecByFlag(quietTarget(f, deps), 2, deps),
|
|
2842
|
-
socket: (f) => cloexecByFlag(f, 1, deps),
|
|
2843
|
-
accept4: (f) => cloexecByFlag(f, 3, deps),
|
|
2844
|
-
...pty ? { ioctl: (f) => ptyIoctl(f, { fs: deps.fs, heap: deps.heap, kernel: pty }) } : {}
|
|
2845
|
-
};
|
|
2846
|
-
}
|
|
2847
|
-
function kernelTimer(setitimer, timer) {
|
|
2848
|
-
return (which, ms) => {
|
|
2849
|
-
if (which !== 0) return setitimer(which, ms);
|
|
2850
|
-
timer.arm(ms ?? 0);
|
|
2851
|
-
return 0;
|
|
2852
|
-
};
|
|
2853
|
-
}
|
|
2854
|
-
function syscallOf(glue, name2, value2) {
|
|
2855
|
-
const names = Object.keys(IMPORT_NAMES);
|
|
2856
|
-
const own = names.find((key) => glue[key] !== void 0 && glue[key] === value2);
|
|
2857
|
-
if (own) return own;
|
|
2858
|
-
return typeof value2 === "function" ? names.find((key) => glue[key] !== void 0 && IMPORT_NAMES[key] === name2) : void 0;
|
|
2859
|
-
}
|
|
2860
|
-
function wrapCloexecSyscalls(imports, glue, deps) {
|
|
2861
|
-
if (!glue) return;
|
|
2862
|
-
const factories = wrapperFactories(deps);
|
|
2863
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2864
|
-
for (const namespace of Object.values(imports)) {
|
|
2865
|
-
if (!namespace || typeof namespace !== "object" || seen.has(namespace)) continue;
|
|
2866
|
-
seen.add(namespace);
|
|
2867
|
-
for (const [name2, value2] of Object.entries(namespace)) {
|
|
2868
|
-
const key = syscallOf(glue, name2, value2);
|
|
2869
|
-
const wrap2 = key && factories[key];
|
|
2870
|
-
if (wrap2) namespace[name2] = wrap2(value2);
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
function pathOpensLinks(Fs) {
|
|
2875
|
-
const fs = Fs;
|
|
2876
|
-
const { mayOpen, isLink } = fs;
|
|
2877
|
-
if (!mayOpen || !isLink) return;
|
|
2878
|
-
fs.mayOpen = (node, flags) => flags & O_PATH2 && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
|
|
2879
|
-
}
|
|
2880
|
-
function importKey(namespace, name2, glue) {
|
|
2881
|
-
const own = glue?.[name2];
|
|
2882
|
-
if (typeof own === "function") {
|
|
2883
|
-
const found = Object.keys(namespace).find((k) => namespace[k] === own);
|
|
2884
|
-
if (found !== void 0) return found;
|
|
2885
|
-
}
|
|
2886
|
-
const literal = LITERALS[name2];
|
|
2887
|
-
return typeof namespace[literal] === "function" ? literal : void 0;
|
|
2888
|
-
}
|
|
2889
|
-
function wrapImport(imports, name2, glue, wrap2, optional = false) {
|
|
2890
|
-
let wrapped = false;
|
|
2891
|
-
for (const ns of namespaces(imports)) {
|
|
2892
|
-
const key = importKey(ns, name2, glue);
|
|
2893
|
-
if (key === void 0) continue;
|
|
2894
|
-
ns[key] = wrap2(ns[key]);
|
|
2895
|
-
wrapped = true;
|
|
2896
|
-
}
|
|
2897
|
-
if (!wrapped && !optional && typeof glue?.[name2] === "function") {
|
|
2898
|
-
throw new Error(`slicc-kernel cannot find the glue's ${LITERALS[name2]} among its imports`);
|
|
2899
|
-
}
|
|
2900
|
-
}
|
|
2901
|
-
function kernelUmask(imports, deps) {
|
|
2902
|
-
let umask = deps.initial & 511;
|
|
2903
|
-
const { glue } = deps;
|
|
2904
|
-
wrapImport(imports, "openat", glue, (openat) => (dirfd, path, flags, varargs) => {
|
|
2905
|
-
const memory = deps.memory();
|
|
2906
|
-
if (flags & O_CREAT2 && varargs && memory) new Int32Array(memory.buffer)[varargs >> 2] &= ~umask;
|
|
2907
|
-
return openat(dirfd, path, flags, varargs);
|
|
2908
|
-
});
|
|
2909
|
-
wrapImport(
|
|
2910
|
-
imports,
|
|
2911
|
-
"mkdirat",
|
|
2912
|
-
glue,
|
|
2913
|
-
(mkdirat) => (dirfd, path, mode) => mkdirat(dirfd, path, mode & ~umask)
|
|
2914
|
-
);
|
|
2915
|
-
wrapImport(
|
|
2916
|
-
imports,
|
|
2917
|
-
"mknodat",
|
|
2918
|
-
glue,
|
|
2919
|
-
(mknodat) => (dirfd, path, mode, dev) => mknodat(dirfd, path, mode & ~umask, dev)
|
|
2920
|
-
);
|
|
2921
|
-
wrapImport(imports, "umask", glue, (own) => {
|
|
2922
|
-
own(umask);
|
|
2923
|
-
return (mask) => {
|
|
2924
|
-
const old = umask;
|
|
2925
|
-
umask = mask & 511;
|
|
2926
|
-
own(umask);
|
|
2927
|
-
deps.set(umask);
|
|
2928
|
-
return old;
|
|
2929
|
-
};
|
|
2930
|
-
});
|
|
2931
|
-
}
|
|
2932
|
-
function touching(times, memory) {
|
|
2933
|
-
if (times === 0) return true;
|
|
2934
|
-
if (!memory) return false;
|
|
2935
|
-
const heap = new Int32Array(memory.buffer);
|
|
2936
|
-
const nsec = [heap[times + 8 >> 2], heap[times + 24 >> 2]];
|
|
2937
|
-
return nsec.every((n) => n === UTIME_NOW || n === UTIME_OMIT);
|
|
2938
|
-
}
|
|
2939
|
-
function touch(Fs, on, run) {
|
|
2940
|
-
if (!Fs || !on) return run();
|
|
2941
|
-
Fs.sliccTouch = true;
|
|
2942
|
-
try {
|
|
2943
|
-
return run();
|
|
2944
|
-
} finally {
|
|
2945
|
-
Fs.sliccTouch = void 0;
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
|
-
function noFollowUtimes(imports, fs, glue, memory = () => void 0) {
|
|
2949
|
-
wrapImport(
|
|
2950
|
-
imports,
|
|
2951
|
-
"utimensat",
|
|
2952
|
-
{ utimensat: glue },
|
|
2953
|
-
(utimensat) => (dirfd, path, times, flags) => {
|
|
2954
|
-
const Fs = fs();
|
|
2955
|
-
const on = touching(times, memory());
|
|
2956
|
-
const { utime, lookupPath, ErrnoError } = Fs ?? {};
|
|
2957
|
-
if (!Fs || !(flags & AT_SYMLINK_NOFOLLOW) || !utime || !lookupPath || !ErrnoError) {
|
|
2958
|
-
return touch(Fs, on, () => utimensat(dirfd, path, times, flags));
|
|
2959
|
-
}
|
|
2960
|
-
Fs.utime = (at, atime, mtime) => {
|
|
2961
|
-
const { node } = lookupPath.call(Fs, at, { follow: false });
|
|
2962
|
-
if (!node.node_ops.setattr) throw new ErrnoError(EMSCRIPTEN_EPERM);
|
|
2963
|
-
node.node_ops.setattr(node, { atime, mtime });
|
|
2964
|
-
};
|
|
2965
|
-
try {
|
|
2966
|
-
return touch(Fs, on, () => utimensat(dirfd, path, times, flags));
|
|
2967
|
-
} finally {
|
|
2968
|
-
Fs.utime = utime;
|
|
2969
|
-
}
|
|
2970
|
-
}
|
|
2971
|
-
);
|
|
2972
|
-
}
|
|
2973
|
-
function errnoOf(err) {
|
|
2974
|
-
const { errno: errno2, code: code2 } = err ?? {};
|
|
2975
|
-
if (typeof errno2 === "number") return errno2;
|
|
2976
|
-
if (typeof code2 === "string") return wasiErrno(code2);
|
|
2977
|
-
throw err;
|
|
2978
|
-
}
|
|
2979
|
-
function persistsItself(stream) {
|
|
2980
|
-
const type = stream.node.mount?.type;
|
|
2981
|
-
return typeof type?.syncfs === "function";
|
|
2982
|
-
}
|
|
2983
|
-
function namespaces(imports) {
|
|
2984
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2985
|
-
for (const namespace of Object.values(imports)) {
|
|
2986
|
-
if (namespace && typeof namespace === "object") seen.add(namespace);
|
|
2987
|
-
}
|
|
2988
|
-
return [...seen];
|
|
2989
|
-
}
|
|
2990
|
-
function keyOf(namespace, name2, glue) {
|
|
2991
|
-
const own = glue?.[name2];
|
|
2992
|
-
const found = typeof own === "function" ? Object.keys(namespace).find((k) => namespace[k] === own) : void 0;
|
|
2993
|
-
return found ?? (typeof namespace[name2] === "function" ? name2 : void 0);
|
|
2994
|
-
}
|
|
2995
|
-
function syncFsync(imports, fs, glue) {
|
|
2996
|
-
for (const namespace of namespaces(imports)) {
|
|
2997
|
-
const key = keyOf(namespace, "fd_sync", glue);
|
|
2998
|
-
const original = key === void 0 ? void 0 : namespace[key];
|
|
2999
|
-
if (key === void 0 || !original?.isAsync) continue;
|
|
3000
|
-
namespace[key] = (fd) => {
|
|
3001
|
-
const stream = fs()?.getStream(fd);
|
|
3002
|
-
if (!stream) return EBADF;
|
|
3003
|
-
if (persistsItself(stream)) return original(fd);
|
|
3004
|
-
try {
|
|
3005
|
-
const result = stream.stream_ops.fsync?.(stream);
|
|
3006
|
-
return typeof result === "number" ? result : 0;
|
|
3007
|
-
} catch (err) {
|
|
3008
|
-
return errnoOf(err);
|
|
3009
|
-
}
|
|
3010
|
-
};
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
function offsetOf(rest2) {
|
|
3014
|
-
const at = rest2.length >= 3 ? Number(rest2[1]) * 2 ** 32 + (Number(rest2[0]) >>> 0) : Number(BigInt.asIntN(64, BigInt(rest2[0])));
|
|
3015
|
-
return at >= 0 && Number.isSafeInteger(at) ? at : void 0;
|
|
3016
|
-
}
|
|
3017
|
-
function readInto(sys, kfd, target, at) {
|
|
3018
|
-
let done = 0;
|
|
3019
|
-
while (done < target.length) {
|
|
3020
|
-
const got = sys.pread?.(kfd, target.length - done, at + done) ?? new Uint8Array(0);
|
|
3021
|
-
if (got.length === 0) break;
|
|
3022
|
-
target.set(got, done);
|
|
3023
|
-
done += got.length;
|
|
3024
|
-
}
|
|
3025
|
-
return done;
|
|
3026
|
-
}
|
|
3027
|
-
function positioned(original, write2, deps) {
|
|
3028
|
-
return (fd, iov, iovcnt, ...rest2) => {
|
|
3029
|
-
const stream = deps.fs()?.getStream(Number(fd));
|
|
3030
|
-
const memory = deps.memory();
|
|
3031
|
-
const kfd = stream?.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
3032
|
-
if (kfd === void 0 || !memory || !(write2 ? deps.sys.pwrite : deps.sys.pread)) {
|
|
3033
|
-
return original(fd, iov, iovcnt, ...rest2);
|
|
3034
|
-
}
|
|
3035
|
-
const at = offsetOf(rest2);
|
|
3036
|
-
if (at === void 0) return wasiErrno("EINVAL");
|
|
3037
|
-
const view = new DataView(memory.buffer);
|
|
3038
|
-
let done = 0;
|
|
3039
|
-
try {
|
|
3040
|
-
for (let i = 0; i < Number(iovcnt); i++) {
|
|
3041
|
-
const ptr = view.getUint32(Number(iov) + i * 8, true);
|
|
3042
|
-
const len = view.getUint32(Number(iov) + i * 8 + 4, true);
|
|
3043
|
-
const part = new Uint8Array(memory.buffer, ptr, len);
|
|
3044
|
-
const moved = write2 ? deps.sys.pwrite?.(kfd, part.slice(), at + done) ?? 0 : readInto(deps.sys, kfd, part, at + done);
|
|
3045
|
-
done += moved;
|
|
3046
|
-
if (moved < len) break;
|
|
3047
|
-
}
|
|
3048
|
-
} catch (err) {
|
|
3049
|
-
return errnoOf(err);
|
|
3050
|
-
}
|
|
3051
|
-
view.setUint32(Number(rest2[rest2.length - 1]), done, true);
|
|
3052
|
-
return 0;
|
|
3053
|
-
};
|
|
3054
|
-
}
|
|
3055
|
-
function positionalIo(imports, deps) {
|
|
3056
|
-
for (const namespace of namespaces(imports)) {
|
|
3057
|
-
for (const [name2, write2] of [
|
|
3058
|
-
["fd_pread", false],
|
|
3059
|
-
["fd_pwrite", true]
|
|
3060
|
-
]) {
|
|
3061
|
-
const key = keyOf(namespace, name2, deps.glue);
|
|
3062
|
-
if (key !== void 0) {
|
|
3063
|
-
namespace[key] = positioned(namespace[key], write2, deps);
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
function staging(Fs, length) {
|
|
3069
|
-
try {
|
|
3070
|
-
return new Uint8Array(length);
|
|
3071
|
-
} catch {
|
|
3072
|
-
throw new Fs.ErrnoError(wasiErrno("ENOMEM"));
|
|
3073
|
-
}
|
|
3074
|
-
}
|
|
3075
|
-
function useFileMmap(Fs, deps) {
|
|
3076
|
-
const fs = Fs;
|
|
3077
|
-
const mmap = fs.mmap;
|
|
3078
|
-
if (typeof mmap !== "function") return;
|
|
3079
|
-
fs.mmap = (stream, length, position, prot, flags) => {
|
|
3080
|
-
const memalign = deps.memalign();
|
|
3081
|
-
const memory = deps.memory();
|
|
3082
|
-
const shared = (flags & MAP_TYPE) !== MAP_PRIVATE && (prot & PROT_WRITE) !== 0;
|
|
3083
|
-
const kfd = stream.sliccKernelFile ? stream.sliccKernelFd : void 0;
|
|
3084
|
-
if (shared && kfd !== void 0) throw new Fs.ErrnoError(wasiErrno("ENODEV"));
|
|
3085
|
-
if (stream.stream_ops.mmap && kfd === void 0 || !memalign || !memory || length <= 0 || shared || (stream.flags & O_ACCMODE2) === O_WRONLY || !Fs.isFile(stream.node.mode)) {
|
|
3086
|
-
return mmap.call(fs, stream, length, position, prot, flags);
|
|
3087
|
-
}
|
|
3088
|
-
const data = staging(Fs, length);
|
|
3089
|
-
let done = 0;
|
|
3090
|
-
try {
|
|
3091
|
-
if (kfd !== void 0) done = readInto(deps.sys, kfd, data, position);
|
|
3092
|
-
else {
|
|
3093
|
-
for (let got = 1; done < length && got > 0; done += got) {
|
|
3094
|
-
got = Fs.read(stream, data, done, length - done, position + done);
|
|
3095
|
-
}
|
|
3096
|
-
}
|
|
3097
|
-
} catch (err) {
|
|
3098
|
-
throw new Fs.ErrnoError(errnoOf(err));
|
|
3099
|
-
}
|
|
3100
|
-
const size = Math.ceil(length / MAP_ALIGN) * MAP_ALIGN;
|
|
3101
|
-
const ptr = memalign(MAP_ALIGN, size);
|
|
3102
|
-
if (!ptr) throw new Fs.ErrnoError(wasiErrno("ENOMEM"));
|
|
3103
|
-
const target = new Uint8Array(memory.buffer, ptr, size);
|
|
3104
|
-
target.fill(0);
|
|
3105
|
-
target.set(data.subarray(0, done));
|
|
3106
|
-
return { ptr, allocated: true };
|
|
3107
|
-
};
|
|
3108
|
-
}
|
|
3109
|
-
function wasmMemory(instance, imports) {
|
|
3110
|
-
const isMemory = (v) => v instanceof WebAssembly.Memory;
|
|
3111
|
-
const exported = Object.values(instance.exports).find(isMemory);
|
|
3112
|
-
if (exported) return exported;
|
|
3113
|
-
for (const namespace of Object.values(imports)) {
|
|
3114
|
-
const found = Object.values(namespace ?? {}).find(isMemory);
|
|
3115
|
-
if (found) return found;
|
|
3116
|
-
}
|
|
3117
|
-
return void 0;
|
|
3118
|
-
}
|
|
3119
|
-
function fdOfPath(path, cwd) {
|
|
3120
|
-
const parts = [];
|
|
3121
|
-
for (const part of `${path.startsWith("/") ? "" : cwd}/${path}`.split("/")) {
|
|
3122
|
-
if (part === "" || part === ".") continue;
|
|
3123
|
-
if (part === "..") parts.pop();
|
|
3124
|
-
else parts.push(part);
|
|
3125
|
-
}
|
|
3126
|
-
const abs = `/${parts.join("/")}`;
|
|
3127
|
-
const std = ["/dev/stdin", "/dev/stdout", "/dev/stderr"].indexOf(abs);
|
|
3128
|
-
if (std >= 0) return std;
|
|
3129
|
-
const m = /^\/(?:dev|proc\/self)\/fd\/(\d+)$/.exec(abs);
|
|
3130
|
-
return m ? Number(m[1]) : void 0;
|
|
3131
|
-
}
|
|
3132
|
-
function syntheticAttr(mode, ino) {
|
|
3133
|
-
const now = /* @__PURE__ */ new Date();
|
|
3134
|
-
return {
|
|
3135
|
-
dev: 1,
|
|
3136
|
-
ino,
|
|
3137
|
-
mode,
|
|
3138
|
-
nlink: 1,
|
|
3139
|
-
uid: 0,
|
|
3140
|
-
gid: 0,
|
|
3141
|
-
rdev: 0,
|
|
3142
|
-
size: 0,
|
|
3143
|
-
atime: now,
|
|
3144
|
-
mtime: now,
|
|
3145
|
-
ctime: now,
|
|
3146
|
-
blksize: 4096,
|
|
3147
|
-
blocks: 0
|
|
3148
|
-
};
|
|
3149
|
-
}
|
|
3150
|
-
function describeFdDir(Fs) {
|
|
3151
|
-
let dir;
|
|
3152
|
-
try {
|
|
3153
|
-
dir = Fs.lookupPath?.("/proc/self/fd", { follow: true })?.node;
|
|
3154
|
-
} catch {
|
|
3155
|
-
return;
|
|
3156
|
-
}
|
|
3157
|
-
const ops = dir?.node_ops;
|
|
3158
|
-
const lookup2 = ops?.lookup;
|
|
3159
|
-
if (!dir || !lookup2 || ops.getattr) return;
|
|
3160
|
-
dir.node_ops = {
|
|
3161
|
-
...ops,
|
|
3162
|
-
getattr: () => syntheticAttr(DIR_MODE, 1),
|
|
3163
|
-
lookup: (parent, name2) => {
|
|
3164
|
-
const entry = lookup2(parent, name2);
|
|
3165
|
-
entry.node_ops = {
|
|
3166
|
-
...entry.node_ops,
|
|
3167
|
-
getattr: () => syntheticAttr(LINK_MODE, entry.id ?? 0)
|
|
3168
|
-
};
|
|
3169
|
-
return entry;
|
|
3170
|
-
}
|
|
3171
|
-
};
|
|
3172
|
-
}
|
|
3173
|
-
function useZeroDevices(Fs) {
|
|
3174
|
-
const { analyzePath, registerDevice, mkdev, makedev } = Fs;
|
|
3175
|
-
if (!analyzePath || !registerDevice || !mkdev || !makedev) return;
|
|
3176
|
-
const zeros = (_s, buffer, offset, length) => {
|
|
3177
|
-
buffer.fill(0, offset, offset + length);
|
|
3178
|
-
return length;
|
|
3179
|
-
};
|
|
3180
|
-
const devices = [
|
|
3181
|
-
["/dev/zero", 5, (_s, _b, _o, length) => length],
|
|
3182
|
-
[
|
|
3183
|
-
"/dev/full",
|
|
3184
|
-
7,
|
|
3185
|
-
(_s, _b, _o, length) => {
|
|
3186
|
-
if (length > 0) throw new Fs.ErrnoError(wasiErrno("ENOSPC"));
|
|
3187
|
-
return 0;
|
|
3188
|
-
}
|
|
3189
|
-
]
|
|
3190
|
-
];
|
|
3191
|
-
for (const [path, minor, write2] of devices) {
|
|
3192
|
-
if (analyzePath.call(Fs, path).exists) continue;
|
|
3193
|
-
const dev = makedev.call(Fs, 1, minor);
|
|
3194
|
-
registerDevice.call(Fs, dev, { read: zeros, write: write2, llseek: () => 0 });
|
|
3195
|
-
mkdev.call(Fs, path, CHAR_DEVICE, dev);
|
|
3196
|
-
}
|
|
3197
|
-
}
|
|
3198
|
-
function linkStdio(Fs) {
|
|
3199
|
-
const { unlink, symlink } = Fs;
|
|
3200
|
-
if (!unlink || !symlink) return;
|
|
3201
|
-
for (const [fd, name2] of ["stdin", "stdout", "stderr"].entries()) {
|
|
3202
|
-
try {
|
|
3203
|
-
unlink.call(Fs, `/dev/${name2}`);
|
|
3204
|
-
} catch {
|
|
3205
|
-
}
|
|
3206
|
-
try {
|
|
3207
|
-
symlink.call(Fs, `/proc/self/fd/${fd}`, `/dev/${name2}`);
|
|
3208
|
-
} catch {
|
|
3209
|
-
}
|
|
3210
|
-
}
|
|
3211
|
-
}
|
|
3212
|
-
function useDevFd(Fs) {
|
|
3213
|
-
if (typeof Fs.open !== "function") return;
|
|
3214
|
-
try {
|
|
3215
|
-
Fs.symlink?.("/proc/self/fd", "/dev/fd");
|
|
3216
|
-
} catch {
|
|
3217
|
-
}
|
|
3218
|
-
linkStdio(Fs);
|
|
3219
|
-
describeFdDir(Fs);
|
|
3220
|
-
const fdOf = (path) => typeof path === "string" ? fdOfPath(path, Fs.cwd()) : void 0;
|
|
3221
|
-
const target = (fd) => {
|
|
3222
|
-
const stream = Fs.getStream(fd);
|
|
3223
|
-
if (!stream) throw new Fs.ErrnoError(wasiErrno("EBADF"));
|
|
3224
|
-
return stream;
|
|
3225
|
-
};
|
|
3226
|
-
const open = Fs.open.bind(Fs);
|
|
3227
|
-
Fs.open = (path, flags, mode) => {
|
|
3228
|
-
const fd = fdOf(path);
|
|
3229
|
-
if (fd === void 0) return open(path, flags, mode);
|
|
3230
|
-
const copy2 = Fs.dupStream(target(fd), -1);
|
|
3231
|
-
setCloseOnExec(copy2, typeof flags === "number" && (flags & O_CLOEXEC) !== 0);
|
|
3232
|
-
return copy2;
|
|
3233
|
-
};
|
|
3234
|
-
const { stat, fstat } = Fs;
|
|
3235
|
-
if (typeof stat !== "function" || typeof fstat !== "function") return;
|
|
3236
|
-
Fs.stat = (path, dontFollow) => {
|
|
3237
|
-
const fd = dontFollow ? void 0 : fdOf(path);
|
|
3238
|
-
if (fd === void 0) return stat.call(Fs, path, dontFollow);
|
|
3239
|
-
target(fd);
|
|
3240
|
-
return fstat.call(Fs, fd);
|
|
3241
|
-
};
|
|
3242
|
-
}
|
|
3243
|
-
function pinRootKind() {
|
|
3244
|
-
pinnedRoot = rootKind();
|
|
3245
|
-
}
|
|
3246
|
-
function mountTable(mounts = []) {
|
|
3247
|
-
const root = pinnedRoot ?? rootKind();
|
|
3248
|
-
const lines = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
3249
|
-
for (const m of mounts) {
|
|
3250
|
-
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
3251
|
-
if (m.state !== "ok") options.push(m.state);
|
|
3252
|
-
const access = options.includes("ro") ? [] : ["rw"];
|
|
3253
|
-
lines.push(
|
|
3254
|
-
`${field(m.source)} ${field(m.target)} ${m.type} ${[...access, ...options].join(",")} 0 0`
|
|
3255
|
-
);
|
|
3256
|
-
}
|
|
3257
|
-
return `${lines.join("\n")}
|
|
3258
|
-
`;
|
|
3259
|
-
}
|
|
3260
|
-
function accounts(env = {}) {
|
|
3261
|
-
const user = env.USER ?? "web_user";
|
|
3262
|
-
const name2 = NAME.test(user) && user !== "root" ? user : "user";
|
|
3263
|
-
const home = env.HOME || "/home";
|
|
3264
|
-
return {
|
|
3265
|
-
passwd: `root:x:0:0:root:/root:/bin/sh
|
|
3266
|
-
${name2}:x:1000:1000:${name2}:${home}:/bin/bash
|
|
3267
|
-
`,
|
|
3268
|
-
group: `root:x:0:
|
|
3269
|
-
${name2}:x:1000:
|
|
3270
|
-
`
|
|
3271
|
-
};
|
|
3272
|
-
}
|
|
3273
|
-
function useMounts(Fs, env = {}, live = false) {
|
|
3274
|
-
const { writeFile, mkdirTree } = Fs;
|
|
3275
|
-
if (typeof Fs.open !== "function" || typeof writeFile !== "function") return;
|
|
3276
|
-
const { passwd, group } = accounts(env);
|
|
3277
|
-
const backing = { "/etc/mtab": "/proc/mounts" };
|
|
3278
|
-
try {
|
|
3279
|
-
if (!live) writeFile.call(Fs, "/proc/mounts", mountTable());
|
|
3280
|
-
} catch {
|
|
3281
|
-
return;
|
|
3282
|
-
}
|
|
3283
|
-
try {
|
|
3284
|
-
mkdirTree.call(Fs, "/dev/.etc");
|
|
3285
|
-
writeFile.call(Fs, "/dev/.etc/passwd", passwd);
|
|
3286
|
-
writeFile.call(Fs, "/dev/.etc/group", group);
|
|
3287
|
-
writeFile.call(Fs, "/dev/.etc/hosts", hostsFile(hostnameOf(env)));
|
|
3288
|
-
writeFile.call(Fs, "/dev/.etc/hostname", `${hostnameOf(env)}
|
|
3289
|
-
`);
|
|
3290
|
-
backing["/etc/passwd"] = "/dev/.etc/passwd";
|
|
3291
|
-
backing["/etc/group"] = "/dev/.etc/group";
|
|
3292
|
-
backing["/etc/hosts"] = "/dev/.etc/hosts";
|
|
3293
|
-
backing["/etc/hostname"] = "/dev/.etc/hostname";
|
|
3294
|
-
} catch {
|
|
3295
|
-
}
|
|
3296
|
-
const open = Fs.open.bind(Fs);
|
|
3297
|
-
Fs.open = (path, flags, mode) => {
|
|
3298
|
-
const instead = backing[path];
|
|
3299
|
-
if (!instead || (flags & (O_ACCMODE2 | O_CREAT2)) !== 0) return open(path, flags, mode);
|
|
3300
|
-
try {
|
|
3301
|
-
return open(path, flags, mode);
|
|
3302
|
-
} catch (e) {
|
|
3303
|
-
if (e?.errno !== wasiErrno("ENOENT")) throw e;
|
|
3304
|
-
return open(instead, flags, mode);
|
|
3305
|
-
}
|
|
3306
|
-
};
|
|
3307
|
-
}
|
|
3308
|
-
function cString(memory, at) {
|
|
3309
|
-
const bytes = new Uint8Array(memory.buffer, at);
|
|
3310
|
-
return new TextDecoder().decode(bytes.subarray(0, bytes.indexOf(0)));
|
|
3311
|
-
}
|
|
3312
|
-
function baseOf(Fs, dirfd) {
|
|
3313
|
-
return dirfd === AT_FDCWD ? Fs.cwd?.() ?? "/" : Fs.getStream?.(dirfd)?.path ?? "/";
|
|
3314
|
-
}
|
|
3315
|
-
function readonlyRefusal(Fs, memory, call2) {
|
|
3316
|
-
if (!(call2.amode & W_ACCESS)) return 0;
|
|
3317
|
-
try {
|
|
3318
|
-
const name2 = cString(memory, call2.path);
|
|
3319
|
-
const abs = name2.startsWith("/") ? name2 : `${baseOf(Fs, call2.dirfd)}/${name2}`;
|
|
3320
|
-
const follow2 = (call2.flags & AT_SYMLINK_NOFOLLOW) === 0;
|
|
3321
|
-
const { node } = Fs.lookupPath.call(Fs, abs, {
|
|
3322
|
-
follow: follow2
|
|
3323
|
-
});
|
|
3324
|
-
const bridge = node.live ? node.mount.opts.bridge : void 0;
|
|
3325
|
-
const stats = bridge;
|
|
3326
|
-
const stat = follow2 ? stats?.stat : stats?.lstat;
|
|
3327
|
-
return stat?.call(stats, liveNodePath(node)).readonly ? -wasiErrno("EROFS") : 0;
|
|
3328
|
-
} catch {
|
|
3329
|
-
return 0;
|
|
3330
|
-
}
|
|
3331
|
-
}
|
|
3332
|
-
function kernelChecks(Fs, memory, call2) {
|
|
3333
|
-
const name2 = cString(memory, call2.path);
|
|
3334
|
-
const abs = name2.startsWith("/") ? name2 : `${baseOf(Fs, call2.dirfd)}/${name2}`;
|
|
3335
|
-
const lookupPath = Fs.lookupPath;
|
|
3336
|
-
const { node } = lookupPath.call(Fs, abs, { follow: (call2.flags & AT_SYMLINK_NOFOLLOW) === 0 });
|
|
3337
|
-
const bridge = node.live ? node.mount.opts.bridge : void 0;
|
|
3338
|
-
if (!bridge?.owners || !bridge.access) return 0;
|
|
3339
|
-
const kind = call2.flags & AT_EACCESS ? "eaccess" : "access";
|
|
3340
|
-
bridge.access(liveNodePath(node), call2.amode, kind, (call2.flags & AT_SYMLINK_NOFOLLOW) !== 0);
|
|
3341
|
-
return 0;
|
|
3342
|
-
}
|
|
3343
|
-
function kernelAccess(imports, fs, memory, glue) {
|
|
3344
|
-
wrapImport(imports, "faccessat", glue, (own) => (dirfd, path, amode, flags) => {
|
|
3345
|
-
const Fs = fs();
|
|
3346
|
-
const heap = memory();
|
|
3347
|
-
const call2 = { dirfd, path, amode: amode & 7, flags };
|
|
3348
|
-
const refused = Fs?.lookupPath && heap ? readonlyRefusal(Fs, heap, call2) : 0;
|
|
3349
|
-
if (refused !== 0) return refused;
|
|
3350
|
-
const rc = own(dirfd, path, amode, flags);
|
|
3351
|
-
if (rc !== 0 || !Fs?.lookupPath || !heap) return rc;
|
|
3352
|
-
try {
|
|
3353
|
-
return kernelChecks(Fs, heap, { dirfd, path, amode: amode & 7, flags });
|
|
3354
|
-
} catch (err) {
|
|
3355
|
-
return -errnoOf(err);
|
|
3356
|
-
}
|
|
3357
|
-
});
|
|
3358
|
-
}
|
|
3359
|
-
function kernelLink(imports, fs, memory, glue) {
|
|
3360
|
-
wrapImport(
|
|
3361
|
-
imports,
|
|
3362
|
-
"linkat",
|
|
3363
|
-
glue,
|
|
3364
|
-
(own) => (olddirfd, oldpath, newdirfd, newpath, flags) => {
|
|
3365
|
-
const Fs = fs();
|
|
3366
|
-
const heap = memory();
|
|
3367
|
-
if (!Fs?.lookupPath || !heap) return own(olddirfd, oldpath, newdirfd, newpath, flags);
|
|
3368
|
-
const at = (dirfd, ptr) => {
|
|
3369
|
-
const name2 = cString(heap, ptr);
|
|
3370
|
-
return name2.startsWith("/") ? name2 : `${baseOf(Fs, dirfd)}/${name2}`;
|
|
3371
|
-
};
|
|
3372
|
-
try {
|
|
3373
|
-
const from = at(olddirfd, oldpath);
|
|
3374
|
-
const to = at(newdirfd, newpath);
|
|
3375
|
-
const follow2 = (flags & AT_SYMLINK_FOLLOW) !== 0;
|
|
3376
|
-
if (linkLive(Fs, from, to, follow2)) return 0;
|
|
3377
|
-
} catch (err) {
|
|
3378
|
-
return -errnoOf(err);
|
|
3379
|
-
}
|
|
3380
|
-
return own(olddirfd, oldpath, newdirfd, newpath, flags);
|
|
3381
|
-
},
|
|
3382
|
-
true
|
|
3383
|
-
);
|
|
3384
|
-
}
|
|
3385
|
-
function kernelChdir(Fs) {
|
|
3386
|
-
const { chdir, lookupPath, ErrnoError } = Fs;
|
|
3387
|
-
if (!chdir || !lookupPath || !ErrnoError) return;
|
|
3388
|
-
Fs.chdir = (path) => {
|
|
3389
|
-
const { node } = lookupPath.call(Fs, path, { follow: true });
|
|
3390
|
-
const directory = Fs.isDir?.(node.mode) === true;
|
|
3391
|
-
const bridge = node.live && directory ? node.mount.opts.bridge : void 0;
|
|
3392
|
-
try {
|
|
3393
|
-
bridge?.access?.(liveNodePath(node), X_ACCESS, "eaccess", false);
|
|
3394
|
-
} catch (err) {
|
|
3395
|
-
throw new ErrnoError(errnoOf(err));
|
|
3396
|
-
}
|
|
3397
|
-
chdir.call(Fs, path);
|
|
3398
|
-
};
|
|
3399
|
-
}
|
|
3400
|
-
function linuxDevices(Fs) {
|
|
3401
|
-
Fs.ignorePermissions = true;
|
|
3402
|
-
kernelChdir(Fs);
|
|
3403
|
-
const { chmod } = Fs;
|
|
3404
|
-
if (!chmod) return;
|
|
3405
|
-
for (const [path, mode] of DEVICE_MODES) {
|
|
3406
|
-
try {
|
|
3407
|
-
chmod.call(Fs, path, mode);
|
|
3408
|
-
} catch {
|
|
3409
|
-
}
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
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, AT_SYMLINK_FOLLOW, DEVICE_MODES;
|
|
3413
|
-
var init_process_fds = __esm({
|
|
3414
|
-
"src/process/process-fds.ts"() {
|
|
3415
|
-
"use strict";
|
|
3416
|
-
init_loopback_names();
|
|
3417
|
-
init_live_vfs_fs();
|
|
3418
|
-
init_process_pty();
|
|
3419
|
-
init_wasi_errno();
|
|
3420
|
-
O_CLOEXEC = 524288;
|
|
3421
|
-
FD_CLOEXEC = 1;
|
|
3422
|
-
F_DUPFD = 0;
|
|
3423
|
-
F_GETFD = 1;
|
|
3424
|
-
F_SETFD = 2;
|
|
3425
|
-
F_GETFL = 3;
|
|
3426
|
-
F_DUPFD_CLOEXEC = 1030;
|
|
3427
|
-
tracked = /* @__PURE__ */ new WeakSet();
|
|
3428
|
-
IMPORT_NAMES = {
|
|
3429
|
-
fcntl: "__syscall_fcntl64",
|
|
3430
|
-
pipe2: "__syscall_pipe2",
|
|
3431
|
-
dup3: "__syscall_dup3",
|
|
3432
|
-
socket: "__syscall_socket",
|
|
3433
|
-
accept4: "__syscall_accept4",
|
|
3434
|
-
ioctl: "__syscall_ioctl",
|
|
3435
|
-
setitimer: "_setitimer_js"
|
|
3436
|
-
};
|
|
3437
|
-
EBADF = 8;
|
|
3438
|
-
AT_SYMLINK_NOFOLLOW = 256;
|
|
3439
|
-
EMSCRIPTEN_EPERM = 63;
|
|
3440
|
-
O_PATH2 = 2097152;
|
|
3441
|
-
LITERALS = {
|
|
3442
|
-
openat: "__syscall_openat",
|
|
3443
|
-
mkdirat: "__syscall_mkdirat",
|
|
3444
|
-
mknodat: "__syscall_mknodat",
|
|
3445
|
-
umask: "__syscall_umask",
|
|
3446
|
-
faccessat: "__syscall_faccessat",
|
|
3447
|
-
linkat: "__syscall_linkat",
|
|
3448
|
-
utimensat: "__syscall_utimensat",
|
|
3449
|
-
getppid: "slicc_getppid_js",
|
|
3450
|
-
resizeHeap: "emscripten_resize_heap",
|
|
3451
|
-
fdWrite: "fd_write",
|
|
3452
|
-
fdRead: "fd_read",
|
|
3453
|
-
sleepMs: "slicc_sleep_ms"
|
|
3690
|
+
throw new SyscallError("ESPIPE");
|
|
3691
|
+
}),
|
|
3692
|
+
read: (s, buffer, offset, length) => this.call(() => {
|
|
3693
|
+
const bytes = this.restarting(() => this.sys.read(kfd, length, nonblocking(s)));
|
|
3694
|
+
buffer.set(bytes, offset);
|
|
3695
|
+
return bytes.length;
|
|
3696
|
+
}),
|
|
3697
|
+
write: (s, buffer, offset, length) => {
|
|
3698
|
+
try {
|
|
3699
|
+
const bytes = buffer.slice(offset, offset + length);
|
|
3700
|
+
return this.restarting(() => this.sys.write(kfd, bytes, nonblocking(s)));
|
|
3701
|
+
} catch (e) {
|
|
3702
|
+
if (e instanceof SyscallError && e.code === "EPIPE" && !this.options.sigpipe?.()) {
|
|
3703
|
+
throw new ProcessExit(KILLED_BY_SIGPIPE);
|
|
3704
|
+
}
|
|
3705
|
+
return this.call(() => {
|
|
3706
|
+
throw e;
|
|
3707
|
+
});
|
|
3708
|
+
}
|
|
3709
|
+
},
|
|
3710
|
+
fsync: () => 0,
|
|
3711
|
+
poll: () => {
|
|
3712
|
+
const state = this.call(() => this.sys.poll(kfd));
|
|
3713
|
+
let mask = 0;
|
|
3714
|
+
if (state.readable) mask |= POLLIN | POLLRDNORM;
|
|
3715
|
+
if (state.writable) mask |= POLLOUT | POLLWRNORM;
|
|
3716
|
+
if (state.hangup) mask |= state.readable ? POLLHUP : POLLERR;
|
|
3717
|
+
return mask;
|
|
3718
|
+
},
|
|
3719
|
+
dup: (stream) => {
|
|
3720
|
+
base.dup?.(stream);
|
|
3721
|
+
this.refs.set(kfd, (this.refs.get(kfd) ?? 0) + 1);
|
|
3722
|
+
},
|
|
3723
|
+
close: (stream) => {
|
|
3724
|
+
if (this.atExit && stream.fd === 2 && this.reporting.size > 0) this.commitStdout();
|
|
3725
|
+
try {
|
|
3726
|
+
base.close?.(stream);
|
|
3727
|
+
} catch {
|
|
3728
|
+
}
|
|
3729
|
+
const left = (this.refs.get(kfd) ?? 1) - 1;
|
|
3730
|
+
if (left > 0) {
|
|
3731
|
+
this.refs.set(kfd, left);
|
|
3732
|
+
return;
|
|
3733
|
+
}
|
|
3734
|
+
this.refs.delete(kfd);
|
|
3735
|
+
if (this.committed.size > 0 && this.committed.delete(kfd)) return;
|
|
3736
|
+
if (this.reporting.size > 0 && this.reporting.delete(kfd)) {
|
|
3737
|
+
this.reportedClose(stream, kfd);
|
|
3738
|
+
return;
|
|
3739
|
+
}
|
|
3740
|
+
try {
|
|
3741
|
+
this.sys.close(kfd);
|
|
3742
|
+
} catch {
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
};
|
|
3746
|
+
}
|
|
3454
3747
|
};
|
|
3455
|
-
UTIME_NOW = 1073741823;
|
|
3456
|
-
UTIME_OMIT = 1073741822;
|
|
3457
|
-
PROT_WRITE = 2;
|
|
3458
|
-
MAP_PRIVATE = 2;
|
|
3459
|
-
MAP_TYPE = 15;
|
|
3460
|
-
O_WRONLY = 1;
|
|
3461
|
-
MAP_ALIGN = 65536;
|
|
3462
|
-
DIR_MODE = 16749;
|
|
3463
|
-
LINK_MODE = 41408;
|
|
3464
|
-
CHAR_DEVICE = 8630;
|
|
3465
|
-
O_ACCMODE2 = 3;
|
|
3466
|
-
O_CREAT2 = 64;
|
|
3467
|
-
field = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
3468
|
-
rootKind = () => globalThis.navigator?.storage ? "opfs" : "memory";
|
|
3469
|
-
NAME = /^[a-z_][a-z0-9_-]*$/i;
|
|
3470
|
-
AT_FDCWD = -100;
|
|
3471
|
-
AT_EACCESS = 512;
|
|
3472
|
-
W_ACCESS = 2;
|
|
3473
|
-
X_ACCESS = 1;
|
|
3474
|
-
AT_SYMLINK_FOLLOW = 1024;
|
|
3475
|
-
DEVICE_MODES = [
|
|
3476
|
-
["/", 493],
|
|
3477
|
-
["/dev", 493],
|
|
3478
|
-
["/dev/null", 438],
|
|
3479
|
-
["/dev/zero", 438],
|
|
3480
|
-
["/dev/full", 438],
|
|
3481
|
-
["/dev/random", 438],
|
|
3482
|
-
["/dev/urandom", 438],
|
|
3483
|
-
["/dev/tty", 438],
|
|
3484
|
-
["/dev/shm", 1023]
|
|
3485
|
-
];
|
|
3486
3748
|
}
|
|
3487
3749
|
});
|
|
3488
3750
|
|
|
@@ -3542,7 +3804,8 @@ function kernelEntry(stream, kernel) {
|
|
|
3542
3804
|
}
|
|
3543
3805
|
const device2 = stream.path === void 0 ? void 0 : NAMED_DEVICES[stream.path];
|
|
3544
3806
|
const kind = stream.sliccKernelFile ? "file" : stream.tty ? "tty" : device2 ?? "stream";
|
|
3545
|
-
|
|
3807
|
+
const access = kind === "tty" ? O_RDWR : (stream.flags ?? O_RDWR) & O_ACCMODE3;
|
|
3808
|
+
return { fd: stream.fd, kernel, kind, flags: access, ...cloexec };
|
|
3546
3809
|
}
|
|
3547
3810
|
function describeInherited(Fs, sys, streams, livePath, actions = []) {
|
|
3548
3811
|
const table = /* @__PURE__ */ new Map();
|
|
@@ -3589,12 +3852,13 @@ function place(Fs, stream, fd) {
|
|
|
3589
3852
|
return moved;
|
|
3590
3853
|
}
|
|
3591
3854
|
function placeholder(Fs, streams, entry) {
|
|
3592
|
-
|
|
3855
|
+
const access = entry.flags ?? O_RDWR;
|
|
3856
|
+
if (entry.kind === "socket") return streams.socketStream(access);
|
|
3593
3857
|
if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR);
|
|
3594
3858
|
if (entry.kind === "stream" || entry.kind === "clipboard" || entry.kind === "sealed")
|
|
3595
|
-
return Fs.open("/dev/null",
|
|
3859
|
+
return Fs.open("/dev/null", access);
|
|
3596
3860
|
Fs.mkdirTree(PLACEHOLDER_DIR);
|
|
3597
|
-
return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`,
|
|
3861
|
+
return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`, access | O_CREAT3);
|
|
3598
3862
|
}
|
|
3599
3863
|
function asFifo(stream, streams, identity) {
|
|
3600
3864
|
const inos = streamInos.get(streams) ?? /* @__PURE__ */ new Map();
|
|
@@ -4295,7 +4559,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
4295
4559
|
var init_version = __esm({
|
|
4296
4560
|
"src/version.ts"() {
|
|
4297
4561
|
"use strict";
|
|
4298
|
-
KERNEL_VERSION = true ? "1.
|
|
4562
|
+
KERNEL_VERSION = true ? "1.93.1" : "0.0.0-dev";
|
|
4299
4563
|
OS_RELEASE = "6.0.0-slicc";
|
|
4300
4564
|
}
|
|
4301
4565
|
});
|
|
@@ -4796,6 +5060,20 @@ function kernelSys(transport) {
|
|
|
4796
5060
|
size(fd) {
|
|
4797
5061
|
return json2(call2({ op: "fd-vfs-stat", fd }, `fd-vfs-stat ${fd}`)).size;
|
|
4798
5062
|
},
|
|
5063
|
+
fdStat(fd) {
|
|
5064
|
+
const r = json2(call2({ op: "fd-vfs-stat", fd, full: true }, `fd-vfs-stat ${fd}`));
|
|
5065
|
+
return r?.stat;
|
|
5066
|
+
},
|
|
5067
|
+
fdChmod(fd, mode) {
|
|
5068
|
+
call2({ op: "fd-chmod", fd, mode }, `fd-chmod ${fd}`);
|
|
5069
|
+
},
|
|
5070
|
+
fdChown(fd, uid, gid) {
|
|
5071
|
+
const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
|
|
5072
|
+
call2({ op: "fd-chown", fd, ...ids }, `fd-chown ${fd}`);
|
|
5073
|
+
},
|
|
5074
|
+
fdUtimes(fd, atimeMs, mtimeMs, now) {
|
|
5075
|
+
call2({ op: "fd-utimes", fd, atimeMs, mtimeMs, now }, `fd-utimes ${fd}`);
|
|
5076
|
+
},
|
|
4799
5077
|
ttyNames() {
|
|
4800
5078
|
return json2(call2({ op: "fd-tty-names" }, "fd-tty-names"));
|
|
4801
5079
|
},
|
|
@@ -4827,6 +5105,9 @@ function kernelSys(transport) {
|
|
|
4827
5105
|
openClipboard(flags) {
|
|
4828
5106
|
return json2(call2({ op: "fd-open-clipboard", flags }, "fd-open-clipboard"));
|
|
4829
5107
|
},
|
|
5108
|
+
clipboardAbort(fd) {
|
|
5109
|
+
call2({ op: "fd-clipboard-abort", fd }, "fd-clipboard-abort");
|
|
5110
|
+
},
|
|
4830
5111
|
ptyNumbers() {
|
|
4831
5112
|
return json2(call2({ op: "pty-list" }, "pty-list"));
|
|
4832
5113
|
},
|
|
@@ -4865,7 +5146,7 @@ function openDevice(Fs, fd, meta) {
|
|
|
4865
5146
|
return openAt(Fs, fd, `/dev/${meta.device}`, accessMode(meta.access));
|
|
4866
5147
|
}
|
|
4867
5148
|
function openHeld(Fs, fd, meta) {
|
|
4868
|
-
return "dir" in meta ? openAt(Fs, fd, meta.dir, O_RDONLY |
|
|
5149
|
+
return "dir" in meta ? openAt(Fs, fd, meta.dir, O_RDONLY | O_DIRECTORY2) : openDevice(Fs, fd, meta);
|
|
4869
5150
|
}
|
|
4870
5151
|
function openAt(Fs, fd, path, flags) {
|
|
4871
5152
|
let stream;
|
|
@@ -4977,6 +5258,17 @@ function kernelWrappers(imports, module, deps) {
|
|
|
4977
5258
|
function bridgeFlags(init) {
|
|
4978
5259
|
return { ...init.owners ? { owners: true } : {}, ...init.links ? { links: true } : {} };
|
|
4979
5260
|
}
|
|
5261
|
+
function credSyncTransport(gated, early, cred) {
|
|
5262
|
+
return {
|
|
5263
|
+
call: (req, timeoutMs, label) => {
|
|
5264
|
+
if (!FS_OPS.has(req.op)) early();
|
|
5265
|
+
const r = gated.call(req, timeoutMs, label);
|
|
5266
|
+
if (cred && req.op === "proc-setcred" && r.ok && r.kind === "json")
|
|
5267
|
+
Object.assign(cred, r.json);
|
|
5268
|
+
return r;
|
|
5269
|
+
}
|
|
5270
|
+
};
|
|
5271
|
+
}
|
|
4980
5272
|
async function runWasmProcess(init, port2, deps = {}) {
|
|
4981
5273
|
const signals = new SignalGate(
|
|
4982
5274
|
createSyncSabTransport(init.sab, port2, {
|
|
@@ -4995,12 +5287,7 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
4995
5287
|
const gated = signals.transport();
|
|
4996
5288
|
let early = () => {
|
|
4997
5289
|
};
|
|
4998
|
-
const transport =
|
|
4999
|
-
call: (req, timeoutMs, label) => {
|
|
5000
|
-
if (!FS_OPS.has(req.op)) early();
|
|
5001
|
-
return gated.call(req, timeoutMs, label);
|
|
5002
|
-
}
|
|
5003
|
-
};
|
|
5290
|
+
const transport = credSyncTransport(gated, () => early(), init.cred);
|
|
5004
5291
|
const sys = kernelSys(transport);
|
|
5005
5292
|
const encoder5 = new TextEncoder();
|
|
5006
5293
|
const say = (fd) => (text) => sys.write(fd, encoder5.encode(`${text}
|
|
@@ -5083,7 +5370,8 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5083
5370
|
const vfs = mountVfsIntoEmscripten(running.FS, {
|
|
5084
5371
|
bridge: createSyncFsSabBridge(transport, bridgeFlags(init)),
|
|
5085
5372
|
cwd: init.cwd,
|
|
5086
|
-
warn: deps.warn ?? say(2)
|
|
5373
|
+
warn: deps.warn ?? say(2),
|
|
5374
|
+
cred: init.owners ? init.cred : void 0
|
|
5087
5375
|
});
|
|
5088
5376
|
early = () => signals.quiet(() => vfs.flushDirty());
|
|
5089
5377
|
const sigpipe = () => running.sliccSigpipe?.() === 1;
|
|
@@ -5102,6 +5390,7 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5102
5390
|
atExit = () => streams.exiting();
|
|
5103
5391
|
useMounts(running.FS, init.env, true);
|
|
5104
5392
|
useZeroDevices(running.FS);
|
|
5393
|
+
useDevRemoval(running.FS);
|
|
5105
5394
|
useProcfs(running.FS, sys, init.pid);
|
|
5106
5395
|
if (init.fork) restoreForkedStreams(running.FS, streams, init.fork.streams ?? []);
|
|
5107
5396
|
else {
|
|
@@ -5111,6 +5400,7 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5111
5400
|
const pipefs = ownValue(running, "PIPEFS");
|
|
5112
5401
|
if (pipefs) streams.usePipes(pipefs);
|
|
5113
5402
|
streams.useControllingTerminal();
|
|
5403
|
+
streams.useKernelFdMetadata();
|
|
5114
5404
|
useDevFd(running.FS);
|
|
5115
5405
|
useFileMmap(running.FS, {
|
|
5116
5406
|
sys,
|
|
@@ -5122,9 +5412,9 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5122
5412
|
transport,
|
|
5123
5413
|
Fs: running.FS,
|
|
5124
5414
|
env: init.env,
|
|
5415
|
+
pid: init.pid,
|
|
5125
5416
|
beforeSpawn: () => vfs.flush(),
|
|
5126
5417
|
afterChild: () => vfs.invalidate(),
|
|
5127
|
-
pid: init.pid,
|
|
5128
5418
|
raise: (sig) => running.sliccRaise?.(sig),
|
|
5129
5419
|
restartable,
|
|
5130
5420
|
memory: () => memory,
|
|
@@ -5144,6 +5434,9 @@ async function runWasmProcess(init, port2, deps = {}) {
|
|
|
5144
5434
|
sigpipe,
|
|
5145
5435
|
restartable
|
|
5146
5436
|
});
|
|
5437
|
+
return runWithFlush(running, init, streams, vfs);
|
|
5438
|
+
}
|
|
5439
|
+
function runWithFlush(running, init, streams, vfs) {
|
|
5147
5440
|
try {
|
|
5148
5441
|
return streams.exitStatus(runMain(running, init));
|
|
5149
5442
|
} finally {
|
|
@@ -5208,7 +5501,7 @@ function runMain(running, init) {
|
|
|
5208
5501
|
return status2;
|
|
5209
5502
|
}
|
|
5210
5503
|
}
|
|
5211
|
-
var FS_OPS, O_RDONLY, O_WRONLY3, O_RDWR3, O_ACCMODE4,
|
|
5504
|
+
var FS_OPS, O_RDONLY, O_WRONLY3, O_RDWR3, O_ACCMODE4, O_DIRECTORY2, accessMode, PLACED, GLUE_TRAILER, evaluateGlue, EVAL_BLOCKED;
|
|
5212
5505
|
var init_process_runtime = __esm({
|
|
5213
5506
|
"src/process/process-runtime.ts"() {
|
|
5214
5507
|
"use strict";
|
|
@@ -5234,7 +5527,7 @@ var init_process_runtime = __esm({
|
|
|
5234
5527
|
O_WRONLY3 = 1;
|
|
5235
5528
|
O_RDWR3 = 2;
|
|
5236
5529
|
O_ACCMODE4 = 3;
|
|
5237
|
-
|
|
5530
|
+
O_DIRECTORY2 = 65536;
|
|
5238
5531
|
accessMode = (access) => access === "read" ? O_RDONLY : access === "write" ? O_WRONLY3 : O_RDWR3;
|
|
5239
5532
|
PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket", "clipboard", "sealed"]);
|
|
5240
5533
|
GLUE_TRAILER = [
|
|
@@ -5360,6 +5653,21 @@ function physicalPath(fs, path) {
|
|
|
5360
5653
|
}
|
|
5361
5654
|
return `/${walk.done.join("/")}`;
|
|
5362
5655
|
}
|
|
5656
|
+
async function physicalPathAsync(fs, path) {
|
|
5657
|
+
const walk = start(path);
|
|
5658
|
+
for (let part = next(walk); part !== void 0; part = next(walk)) {
|
|
5659
|
+
const at = `/${[...walk.done, part].join("/")}`;
|
|
5660
|
+
let target;
|
|
5661
|
+
try {
|
|
5662
|
+
target = (await fs.lstat(at)).isSymbolicLink ? await fs.readlink(at) : void 0;
|
|
5663
|
+
} catch {
|
|
5664
|
+
return rest(walk, part);
|
|
5665
|
+
}
|
|
5666
|
+
if (target === void 0) walk.done.push(part);
|
|
5667
|
+
else if (!follow(walk, target)) return lexical(path);
|
|
5668
|
+
}
|
|
5669
|
+
return `/${walk.done.join("/")}`;
|
|
5670
|
+
}
|
|
5363
5671
|
var MAX_HOPS;
|
|
5364
5672
|
var init_physical_path = __esm({
|
|
5365
5673
|
"src/fs/physical-path.ts"() {
|
|
@@ -5584,9 +5892,11 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
|
|
|
5584
5892
|
...bridge.kept ? { kept: bridge.kept.bind(bridge) } : {},
|
|
5585
5893
|
...bridge.keptStat ? { keptStat: bridge.keptStat.bind(bridge) } : {},
|
|
5586
5894
|
...bridge.pinned ? { pinned: (handle) => pinnedIo2(bridge, handle, rewriting) } : {},
|
|
5587
|
-
...bridge.create ? {
|
|
5895
|
+
...bridge.create ? {
|
|
5896
|
+
create: (p, mode, opening2) => mutating(() => bridge.create?.(p, mode, opening2), ...entry(p))
|
|
5897
|
+
} : {},
|
|
5588
5898
|
...chown ? {
|
|
5589
|
-
chown: (p,
|
|
5899
|
+
chown: (p, ...rest2) => rewriting(p, () => chown.call(bridge, p, ...rest2))
|
|
5590
5900
|
} : {},
|
|
5591
5901
|
...bridge.pread && bridge.pwrite && bridge.truncate ? {
|
|
5592
5902
|
pread: bridge.pread.bind(bridge),
|
|
@@ -6356,6 +6666,7 @@ var init_wasi_fds = __esm({
|
|
|
6356
6666
|
const { buffer } = e.file;
|
|
6357
6667
|
try {
|
|
6358
6668
|
buffer.flush();
|
|
6669
|
+
this.reported.delete(buffer);
|
|
6359
6670
|
} catch (err) {
|
|
6360
6671
|
this.reported.add(buffer);
|
|
6361
6672
|
this.drop(buffer);
|
|
@@ -6421,6 +6732,7 @@ var init_wasi_fds = __esm({
|
|
|
6421
6732
|
for (const buffer of this.buffers.values()) {
|
|
6422
6733
|
try {
|
|
6423
6734
|
buffer.flush();
|
|
6735
|
+
this.reported.delete(buffer);
|
|
6424
6736
|
} catch (err) {
|
|
6425
6737
|
if (!this.reported.has(buffer)) throw err;
|
|
6426
6738
|
}
|
|
@@ -6643,7 +6955,7 @@ var init_wasi_fds = __esm({
|
|
|
6643
6955
|
return true;
|
|
6644
6956
|
}
|
|
6645
6957
|
try {
|
|
6646
|
-
this.fs.create(path);
|
|
6958
|
+
this.fs.create(path, void 0, true);
|
|
6647
6959
|
return true;
|
|
6648
6960
|
} catch (err) {
|
|
6649
6961
|
if (oflags & OFLAGS.EXCL || err.code !== "EEXIST") throw err;
|
|
@@ -6957,7 +7269,7 @@ var init_wasi_termios = __esm({
|
|
|
6957
7269
|
});
|
|
6958
7270
|
|
|
6959
7271
|
// src/process/wasi/wasi-host.ts
|
|
6960
|
-
function
|
|
7272
|
+
function idOf3(value2) {
|
|
6961
7273
|
return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
|
|
6962
7274
|
}
|
|
6963
7275
|
function linkedOf(st) {
|
|
@@ -7034,6 +7346,7 @@ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, AT_EACCESS2, ROOT_IDS, GONE,
|
|
|
7034
7346
|
var init_wasi_host = __esm({
|
|
7035
7347
|
"src/process/wasi/wasi-host.ts"() {
|
|
7036
7348
|
"use strict";
|
|
7349
|
+
init_dev_removal();
|
|
7037
7350
|
init_physical_path();
|
|
7038
7351
|
init_cpu_clock();
|
|
7039
7352
|
init_cred();
|
|
@@ -7131,10 +7444,10 @@ var init_wasi_host = __esm({
|
|
|
7131
7444
|
return path;
|
|
7132
7445
|
};
|
|
7133
7446
|
const modeOf2 = (st) => (st.mode ?? 0) & 4095;
|
|
7134
|
-
const chown = (path, uid, gid, follow2) => {
|
|
7447
|
+
const chown = (path, uid, gid, follow2, handle) => {
|
|
7135
7448
|
const { chown: own } = this.o.fs;
|
|
7136
7449
|
if (!own) throw new WasiError("ENOSYS");
|
|
7137
|
-
own.call(this.o.fs, path,
|
|
7450
|
+
own.call(this.o.fs, path, idOf3(uid), idOf3(gid), follow2, handle);
|
|
7138
7451
|
};
|
|
7139
7452
|
const caller = () => {
|
|
7140
7453
|
const cred = this.o.kernel.call({ op: "proc-cred" });
|
|
@@ -7165,7 +7478,11 @@ var init_wasi_host = __esm({
|
|
|
7165
7478
|
return follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
|
|
7166
7479
|
};
|
|
7167
7480
|
return wrap({
|
|
7168
|
-
fd_chown: (fd, uid, gid) =>
|
|
7481
|
+
fd_chown: (fd, uid, gid) => {
|
|
7482
|
+
const e = fds.get(fd);
|
|
7483
|
+
const handle = e.type === "file" ? e.file.buffer.handle : void 0;
|
|
7484
|
+
void chown(pathOf(fd), uid, gid, true, handle);
|
|
7485
|
+
},
|
|
7169
7486
|
path_chown: (dirfd, p, l, uid, gid, flags) => void chown(at(dirfd, p, l), uid, gid, (flags & AT_SYMLINK_NOFOLLOW2) === 0),
|
|
7170
7487
|
fd_owner: (fd, out) => {
|
|
7171
7488
|
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
@@ -7177,14 +7494,14 @@ var init_wasi_host = __esm({
|
|
|
7177
7494
|
owner(fdOwned(fd), out);
|
|
7178
7495
|
},
|
|
7179
7496
|
path_filestat_owner: (dirfd, lookup2, p, l, statOut, out) => {
|
|
7180
|
-
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
7181
7497
|
const path = at(dirfd, p, l);
|
|
7498
|
+
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
7182
7499
|
this.writeFilestat(statOut, this.pathFilestat(path, lookup2));
|
|
7183
7500
|
owner(pathOwned(path, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
|
|
7184
7501
|
},
|
|
7185
7502
|
path_owner: (dirfd, p, l, flags, out) => {
|
|
7186
|
-
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
7187
7503
|
const path = at(dirfd, p, l);
|
|
7504
|
+
if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
|
|
7188
7505
|
owner(pathOwned(path, (flags & AT_SYMLINK_NOFOLLOW2) === 0), out);
|
|
7189
7506
|
},
|
|
7190
7507
|
path_access: (dirfd, p, l, amode, flags) => {
|
|
@@ -7441,14 +7758,35 @@ var init_wasi_host = __esm({
|
|
|
7441
7758
|
const { mem, fds, o } = this;
|
|
7442
7759
|
const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
|
|
7443
7760
|
return {
|
|
7444
|
-
path_open: (dirfd,
|
|
7445
|
-
const
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7761
|
+
path_open: (dirfd, lookup2, p, l, oflags, rights, _inheriting, fdflags, out) => {
|
|
7762
|
+
const follow2 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
7763
|
+
try {
|
|
7764
|
+
const path = at(dirfd, p, l);
|
|
7765
|
+
if (deviceOf(path)) this.interrupted?.();
|
|
7766
|
+
const fresh = (oflags & OFLAGS.CREAT) !== 0 && !this.synthetic(path) && !o.fs.exists(path);
|
|
7767
|
+
mem.view().setUint32(out, fds.open(path, oflags, rights, fdflags), true);
|
|
7768
|
+
if (fresh) this.created(path, 438);
|
|
7769
|
+
} catch (err) {
|
|
7770
|
+
if (err.code !== "ENOENT") throw err;
|
|
7771
|
+
const raw = mem.string(p, l);
|
|
7772
|
+
const joined2 = raw.startsWith("/") ? raw : `${fds.dir(dirfd).path}/${raw}`;
|
|
7773
|
+
const resolved2 = this.resolveForDev(joined2, follow2);
|
|
7774
|
+
if (!resolved2) throw err;
|
|
7775
|
+
mem.view().setUint32(out, fds.open(resolved2, oflags, rights, fdflags), true);
|
|
7776
|
+
}
|
|
7777
|
+
},
|
|
7778
|
+
path_filestat_get: (dirfd, lookup2, p, l, out) => {
|
|
7779
|
+
try {
|
|
7780
|
+
this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup2));
|
|
7781
|
+
} catch (err) {
|
|
7782
|
+
if (err.code !== "ENOENT") throw err;
|
|
7783
|
+
const raw = mem.string(p, l);
|
|
7784
|
+
const joined2 = raw.startsWith("/") ? raw : `${fds.dir(dirfd).path}/${raw}`;
|
|
7785
|
+
const resolved2 = this.resolveForDev(joined2, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0);
|
|
7786
|
+
if (!resolved2) throw err;
|
|
7787
|
+
this.writeFilestat(out, this.pathFilestat(resolved2, lookup2));
|
|
7788
|
+
}
|
|
7450
7789
|
},
|
|
7451
|
-
path_filestat_get: (dirfd, lookup2, p, l, out) => void this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup2)),
|
|
7452
7790
|
path_filestat_set_times: (dirfd, lookup2, p, l, atim, mtim, flags) => {
|
|
7453
7791
|
const path = at(dirfd, p, l);
|
|
7454
7792
|
fds.flushPath(path);
|
|
@@ -7463,6 +7801,7 @@ var init_wasi_host = __esm({
|
|
|
7463
7801
|
path_remove_directory: (dirfd, p, l) => void o.fs.rmdir(at(dirfd, p, l)),
|
|
7464
7802
|
path_unlink_file: (dirfd, p, l) => {
|
|
7465
7803
|
const path = at(dirfd, p, l);
|
|
7804
|
+
if (inDevTree(path)) return void o.fs.unlink(path);
|
|
7466
7805
|
const st = o.fs.lstat(path);
|
|
7467
7806
|
if (st.isDirectory) throw new WasiError("EISDIR");
|
|
7468
7807
|
const linked = linkedOf(st);
|
|
@@ -7694,7 +8033,12 @@ var init_wasi_host = __esm({
|
|
|
7694
8033
|
const v = this.mem.view();
|
|
7695
8034
|
v.setUint8(out, filetype);
|
|
7696
8035
|
v.setUint16(out + 2, flags, true);
|
|
7697
|
-
|
|
8036
|
+
let rights = seeks ? RIGHTS.ALL : RIGHTS.ALL & ~(RIGHTS.FD_SEEK | RIGHTS.FD_TELL);
|
|
8037
|
+
if (e.type === "kernel") {
|
|
8038
|
+
const access = this.o.kernel.sys.access?.(fd);
|
|
8039
|
+
if (access === "read") rights &= ~RIGHTS.FD_WRITE;
|
|
8040
|
+
else if (access === "write") rights &= ~RIGHTS.FD_READ;
|
|
8041
|
+
}
|
|
7698
8042
|
v.setBigUint64(out + 8, rights, true);
|
|
7699
8043
|
v.setBigUint64(out + 16, RIGHTS.ALL, true);
|
|
7700
8044
|
}
|
|
@@ -7760,6 +8104,21 @@ var init_wasi_host = __esm({
|
|
|
7760
8104
|
synthetic(path) {
|
|
7761
8105
|
return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH2 && !!this.o.kernel.sys.openClipboard;
|
|
7762
8106
|
}
|
|
8107
|
+
resolveForDev(path, follow2 = true) {
|
|
8108
|
+
try {
|
|
8109
|
+
if (!follow2) {
|
|
8110
|
+
const slash = path.lastIndexOf("/");
|
|
8111
|
+
if (slash <= 0) return void 0;
|
|
8112
|
+
const parent = physicalPath(this.o.fs, path.slice(0, slash));
|
|
8113
|
+
const resolved3 = `${parent}/${path.slice(slash + 1)}`;
|
|
8114
|
+
return resolved3 !== path && this.synthetic(resolved3) ? resolved3 : void 0;
|
|
8115
|
+
}
|
|
8116
|
+
const resolved2 = physicalPath(this.o.fs, path);
|
|
8117
|
+
return resolved2 !== path && this.synthetic(resolved2) ? resolved2 : void 0;
|
|
8118
|
+
} catch {
|
|
8119
|
+
return void 0;
|
|
8120
|
+
}
|
|
8121
|
+
}
|
|
7763
8122
|
pathFilestat(path, lookup2) {
|
|
7764
8123
|
if (this.synthetic(path)) {
|
|
7765
8124
|
return this.local({
|
|
@@ -7771,7 +8130,19 @@ var init_wasi_host = __esm({
|
|
|
7771
8130
|
}
|
|
7772
8131
|
this.fds.flushPath(path);
|
|
7773
8132
|
const follow2 = (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0;
|
|
7774
|
-
|
|
8133
|
+
try {
|
|
8134
|
+
return filestatOf(path, follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path));
|
|
8135
|
+
} catch (err) {
|
|
8136
|
+
if (err.code !== "ENOENT") throw err;
|
|
8137
|
+
const resolved2 = this.resolveForDev(path, follow2);
|
|
8138
|
+
if (!resolved2) throw err;
|
|
8139
|
+
return this.local({
|
|
8140
|
+
filetype: FILETYPE.CHARACTER_DEVICE,
|
|
8141
|
+
size: 0n,
|
|
8142
|
+
ino: pathInode(resolved2),
|
|
8143
|
+
mtimeNs: 0n
|
|
8144
|
+
});
|
|
8145
|
+
}
|
|
7775
8146
|
}
|
|
7776
8147
|
setTimes(path, atim, mtim, flags, follow2 = true) {
|
|
7777
8148
|
const asked = FSTFLAGS.ATIM | FSTFLAGS.ATIM_NOW | FSTFLAGS.MTIM | FSTFLAGS.MTIM_NOW;
|
|
@@ -7843,6 +8214,7 @@ var init_wasi_threads = __esm({
|
|
|
7843
8214
|
"src/process/wasi/wasi-threads.ts"() {
|
|
7844
8215
|
"use strict";
|
|
7845
8216
|
init_protocol();
|
|
8217
|
+
init_sync_sab_wire();
|
|
7846
8218
|
init_wasi_files();
|
|
7847
8219
|
LAST_TID = 0;
|
|
7848
8220
|
RUNNING = 1;
|
|
@@ -7878,7 +8250,7 @@ var init_wasi_threads = __esm({
|
|
|
7878
8250
|
this.beforeSpawn?.();
|
|
7879
8251
|
const tid = Atomics.add(this.ids, LAST_TID, 1) + 1;
|
|
7880
8252
|
const modules = this.modules?.();
|
|
7881
|
-
const blocked = this.blocked?.()
|
|
8253
|
+
const blocked = this.blocked?.();
|
|
7882
8254
|
this.port.postMessage({
|
|
7883
8255
|
type: WASM_THREAD_SPAWN,
|
|
7884
8256
|
thread: {
|
|
@@ -7887,7 +8259,7 @@ var init_wasi_threads = __esm({
|
|
|
7887
8259
|
memory: this.memory,
|
|
7888
8260
|
ids: this.ids.buffer,
|
|
7889
8261
|
...modules ? { modules } : {},
|
|
7890
|
-
...blocked ? { blocked } : {}
|
|
8262
|
+
...anyBlocked(blocked) ? { blocked } : {}
|
|
7891
8263
|
}
|
|
7892
8264
|
});
|
|
7893
8265
|
return tid;
|
|
@@ -8108,7 +8480,8 @@ var init_wasix_process = __esm({
|
|
|
8108
8480
|
cwd: this.host.cwd,
|
|
8109
8481
|
...fds.isShared ? { shared: true } : {},
|
|
8110
8482
|
setjmps: this.driver.setjmps(),
|
|
8111
|
-
...this.host.signals ? { signals: this.host.signals.snapshot() } : {}
|
|
8483
|
+
...this.host.signals ? { signals: this.host.signals.snapshot() } : {},
|
|
8484
|
+
...this.host.sigmask ? { blocked: this.host.sigmask.inherited() } : {}
|
|
8112
8485
|
};
|
|
8113
8486
|
return this.call({
|
|
8114
8487
|
op: "proc-fork",
|
|
@@ -8614,7 +8987,7 @@ function procfsBridge(fs, tree) {
|
|
|
8614
8987
|
}
|
|
8615
8988
|
const { chown } = fs;
|
|
8616
8989
|
if (chown) {
|
|
8617
|
-
over.chown = (p,
|
|
8990
|
+
over.chown = (p, ...rest2) => readOnly2([[p, rest2[2] === true]], () => chown.call(fs, p, ...rest2));
|
|
8618
8991
|
}
|
|
8619
8992
|
return new Proxy(fs, {
|
|
8620
8993
|
get: (target, key, receiver) => key in over ? over[key] : Reflect.get(target, key, receiver)
|
|
@@ -8772,7 +9145,7 @@ var init_wasi_sigmask = __esm({
|
|
|
8772
9145
|
};
|
|
8773
9146
|
WasiSigmask = class {
|
|
8774
9147
|
lo;
|
|
8775
|
-
hi
|
|
9148
|
+
hi;
|
|
8776
9149
|
header;
|
|
8777
9150
|
deliver;
|
|
8778
9151
|
process;
|
|
@@ -8781,9 +9154,10 @@ var init_wasi_sigmask = __esm({
|
|
|
8781
9154
|
this.deliver = deliver;
|
|
8782
9155
|
this.process = process;
|
|
8783
9156
|
this.lo = libcBits(Atomics.load(header, SAB_I_BLOCKED));
|
|
9157
|
+
this.hi = Atomics.load(header, SAB_I_BLOCKED_HI);
|
|
8784
9158
|
}
|
|
8785
9159
|
static unsupported(header) {
|
|
8786
|
-
|
|
9160
|
+
storeBlocked(header, [0, 0]);
|
|
8787
9161
|
}
|
|
8788
9162
|
set(how, setLo, setHi, old) {
|
|
8789
9163
|
if (how !== SIG_BLOCK && how !== SIG_UNBLOCK && how !== SIG_SETMASK) return E.INVAL;
|
|
@@ -8791,7 +9165,7 @@ var init_wasi_sigmask = __esm({
|
|
|
8791
9165
|
this.lo = apply(how, this.lo, setLo | 0) & ~LIBC_UNBLOCKABLE;
|
|
8792
9166
|
this.hi = apply(how, this.hi, setHi | 0);
|
|
8793
9167
|
const now = kernelBits(this.lo);
|
|
8794
|
-
|
|
9168
|
+
storeBlocked(this.header, [now, this.hi]);
|
|
8795
9169
|
if ((Atomics.load(this.header, SAB_I_SIGNALS) & ~now) !== 0) this.deliver();
|
|
8796
9170
|
return E.SUCCESS;
|
|
8797
9171
|
}
|
|
@@ -8799,7 +9173,7 @@ var init_wasi_sigmask = __esm({
|
|
|
8799
9173
|
const old = [this.lo, this.hi];
|
|
8800
9174
|
this.lo = setLo & ~LIBC_UNBLOCKABLE;
|
|
8801
9175
|
this.hi = setHi | 0;
|
|
8802
|
-
|
|
9176
|
+
storeBlocked(this.header, [kernelBits(this.lo), this.hi]);
|
|
8803
9177
|
return old;
|
|
8804
9178
|
}
|
|
8805
9179
|
deliverUnblocked() {
|
|
@@ -8812,6 +9186,9 @@ var init_wasi_sigmask = __esm({
|
|
|
8812
9186
|
this.set(SIG_SETMASK, lo, hi, () => {
|
|
8813
9187
|
});
|
|
8814
9188
|
}
|
|
9189
|
+
inherited() {
|
|
9190
|
+
return [kernelBits(this.lo), this.hi];
|
|
9191
|
+
}
|
|
8815
9192
|
discard(sig) {
|
|
8816
9193
|
Atomics.and(this.header, SAB_I_SIGNALS, ~sigbit(sig));
|
|
8817
9194
|
if (this.process) Atomics.and(this.process, SAB_I_SIGNALS, ~sigbit(sig));
|
|
@@ -10789,6 +11166,7 @@ __export(wasi_runtime_exports, {
|
|
|
10789
11166
|
runWasiProcess: () => runWasiProcess,
|
|
10790
11167
|
runWasiThread: () => runWasiThread,
|
|
10791
11168
|
sigmaskOf: () => sigmaskOf,
|
|
11169
|
+
takeThreadDefault: () => takeThreadDefault,
|
|
10792
11170
|
trapMessage: () => trapMessage,
|
|
10793
11171
|
unsupportedImport: () => unsupportedImport,
|
|
10794
11172
|
wireSignals: () => wireSignals
|
|
@@ -10832,7 +11210,7 @@ function sigmaskOf(module, sab, gate, threads, process) {
|
|
|
10832
11210
|
WasiSigmask.unsupported(header);
|
|
10833
11211
|
return void 0;
|
|
10834
11212
|
}
|
|
10835
|
-
if (threads) threads.blocked = () =>
|
|
11213
|
+
if (threads) threads.blocked = () => loadBlocked(header);
|
|
10836
11214
|
const shared = process && new Int32Array(process, 0, SAB_HEADER_I32);
|
|
10837
11215
|
return new WasiSigmask(header, () => gate.deliver(), shared);
|
|
10838
11216
|
}
|
|
@@ -11226,7 +11604,7 @@ async function runWasiThread(init, port2) {
|
|
|
11226
11604
|
masks: () => null,
|
|
11227
11605
|
raise: (sig) => signals.raise(sig)
|
|
11228
11606
|
});
|
|
11229
|
-
const signals = new WasiSignals(
|
|
11607
|
+
const signals = new WasiSignals(takeThreadDefault(call2, init.pid));
|
|
11230
11608
|
const threads = new WasiThreads(port2, thread.memory, threadCap(init.env), thread.tid, thread.ids);
|
|
11231
11609
|
threads.received = thread.modules;
|
|
11232
11610
|
const id = identify(transport, init);
|
|
@@ -11280,7 +11658,7 @@ async function runWasiThread(init, port2) {
|
|
|
11280
11658
|
throw e;
|
|
11281
11659
|
}
|
|
11282
11660
|
}
|
|
11283
|
-
var TRAPPED, PREVIEW1, WASIX, SLICC, SIGNAL_CALLBACK, takeDefault, SLICC_FS, SLICC_TTY, RESERVED2, UNDELIVERED, DELIVERED, importsSlicc, importsSigactionHook, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
|
|
11661
|
+
var TRAPPED, PREVIEW1, WASIX, SLICC, SIGNAL_CALLBACK, takeDefault, takeThreadDefault, SLICC_FS, SLICC_TTY, RESERVED2, UNDELIVERED, DELIVERED, importsSlicc, importsSigactionHook, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
|
|
11284
11662
|
var init_wasi_runtime = __esm({
|
|
11285
11663
|
"src/process/wasi/wasi-runtime.ts"() {
|
|
11286
11664
|
"use strict";
|
|
@@ -11315,6 +11693,17 @@ var init_wasi_runtime = __esm({
|
|
|
11315
11693
|
call2({ op: "proc-kill", pid, sig });
|
|
11316
11694
|
if (defaultAction(sig) === "terminate") throw new WasiExit(128 + sig);
|
|
11317
11695
|
};
|
|
11696
|
+
takeThreadDefault = (call2, pid) => (sig) => {
|
|
11697
|
+
if (defaultAction(sig) !== "terminate") {
|
|
11698
|
+
call2({ op: "proc-kill", pid, sig });
|
|
11699
|
+
return;
|
|
11700
|
+
}
|
|
11701
|
+
try {
|
|
11702
|
+
call2({ op: "proc-kill-self", sig });
|
|
11703
|
+
} catch {
|
|
11704
|
+
}
|
|
11705
|
+
throw new WasiExit(128 + sig);
|
|
11706
|
+
};
|
|
11318
11707
|
SLICC_FS = "slicc_fs";
|
|
11319
11708
|
SLICC_TTY = "slicc_tty";
|
|
11320
11709
|
RESERVED2 = RESERVED_NAMESPACES;
|
|
@@ -11715,6 +12104,8 @@ var init_js_kernel = __esm({
|
|
|
11715
12104
|
|
|
11716
12105
|
// src/process/js/js-children.ts
|
|
11717
12106
|
function exitedOf(status2) {
|
|
12107
|
+
if ((status2 & 255) === 127)
|
|
12108
|
+
return { status: 128 + (status2 >> 8 & 255), signal: status2 >> 8 & 255, stopped: true };
|
|
11718
12109
|
const signal = status2 & 127;
|
|
11719
12110
|
return signal ? { status: 128 + signal, signal } : { status: status2 >> 8 & 255 };
|
|
11720
12111
|
}
|
|
@@ -11751,8 +12142,10 @@ function writable(io, fd) {
|
|
|
11751
12142
|
});
|
|
11752
12143
|
}
|
|
11753
12144
|
function childOps(kernel, io, defaults, sync) {
|
|
11754
|
-
const wait2 = async (pid) => {
|
|
11755
|
-
|
|
12145
|
+
const wait2 = async (pid, options = {}) => {
|
|
12146
|
+
if (typeof options !== "object" || options === null) throw new JsCallError("EINVAL", "wait");
|
|
12147
|
+
const untraced = options.untraced === true ? { untraced: true } : {};
|
|
12148
|
+
const r = await kernel.blocking({ op: "proc-wait", pid, nohang: false, ...untraced });
|
|
11756
12149
|
const [, status2] = r.ok && r.kind === "json" ? r.json : [0, 0];
|
|
11757
12150
|
return exitedOf(status2);
|
|
11758
12151
|
};
|
|
@@ -11766,7 +12159,7 @@ function childOps(kernel, io, defaults, sync) {
|
|
|
11766
12159
|
...stdin !== void 0 ? { stdin: writable(io, stdin) } : {},
|
|
11767
12160
|
...stdout !== void 0 ? { stdout: readable(io, stdout) } : {},
|
|
11768
12161
|
...stderr !== void 0 ? { stderr: readable(io, stderr) } : {},
|
|
11769
|
-
wait: () => wait2(pid),
|
|
12162
|
+
wait: (options) => wait2(pid, options),
|
|
11770
12163
|
kill: (signal) => kill(pid, signal)
|
|
11771
12164
|
};
|
|
11772
12165
|
};
|
|
@@ -12032,6 +12425,7 @@ function* lookup(abs) {
|
|
|
12032
12425
|
const names = yield { op: "fd-tty-names" };
|
|
12033
12426
|
if (names.includes(abs)) return { kind: "terminal", name: abs };
|
|
12034
12427
|
}
|
|
12428
|
+
if (name2 === "pts") return { kind: "dir", mode: DIR | 365 };
|
|
12035
12429
|
const pts = /^pts\/(\d+)$/.exec(name2)?.[1];
|
|
12036
12430
|
if (pts !== void 0) {
|
|
12037
12431
|
const open = yield { op: "pty-list" };
|
|
@@ -12063,7 +12457,8 @@ function* fdStat(fd, path) {
|
|
|
12063
12457
|
if (info.kind === "file") {
|
|
12064
12458
|
const file = yield { op: "fd-vfs-stat", fd };
|
|
12065
12459
|
if (file.orphan) return { ...nodeStat(33152, file.size), isFile: true };
|
|
12066
|
-
|
|
12460
|
+
const st = yield* pathStat(file.path);
|
|
12461
|
+
return { ...st, size: file.size };
|
|
12067
12462
|
}
|
|
12068
12463
|
if (info.terminal) return yield* terminalStat(info.terminal);
|
|
12069
12464
|
if (CHAR_KINDS.has(info.kind)) return nodeStat(CHAR | 438);
|
|
@@ -12116,16 +12511,26 @@ function* devReadlink(abs) {
|
|
|
12116
12511
|
if (node.kind === "fd") return yield* fdTarget(node.fd, abs);
|
|
12117
12512
|
throw new JsCallError("EINVAL", abs);
|
|
12118
12513
|
}
|
|
12514
|
+
function* devResolveTarget(abs) {
|
|
12515
|
+
const node = yield* lookup(abs);
|
|
12516
|
+
if (node.kind === "fd") return yield* fdTarget(node.fd, abs);
|
|
12517
|
+
if (node.kind === "link" && node.fd !== void 0) return yield* fdTarget(node.fd, abs);
|
|
12518
|
+
return void 0;
|
|
12519
|
+
}
|
|
12119
12520
|
function* devReaddir(abs) {
|
|
12120
12521
|
if (abs === "/dev/fd") {
|
|
12121
12522
|
const fds = yield { op: "fd-list" };
|
|
12122
12523
|
return fds.map(({ fd }) => String(fd));
|
|
12123
12524
|
}
|
|
12525
|
+
if (abs === "/dev/pts") {
|
|
12526
|
+
const open = yield { op: "pty-list" };
|
|
12527
|
+
return open.map(String).sort();
|
|
12528
|
+
}
|
|
12124
12529
|
const node = yield* lookup(abs);
|
|
12125
12530
|
if (node.kind !== "dir") throw new JsCallError("ENOTDIR", abs);
|
|
12126
12531
|
const names = yield { op: "fd-tty-names" };
|
|
12127
12532
|
const ttys = names.filter((n) => /^\/dev\/tty\d+$/.test(n)).map((n) => n.slice(5));
|
|
12128
|
-
return [...DEVICES2, "clipboard", "sealed", "tty", "fd", ...STDIO3, ...ttys].sort();
|
|
12533
|
+
return [...DEVICES2, "clipboard", "sealed", "tty", "fd", "pts", ...STDIO3, ...ttys].sort();
|
|
12129
12534
|
}
|
|
12130
12535
|
function* aliasOf(fd, abs, o) {
|
|
12131
12536
|
const info = yield* fdInfo(fd, abs);
|
|
@@ -12134,6 +12539,9 @@ function* aliasOf(fd, abs, o) {
|
|
|
12134
12539
|
const at = yield { op: "fd-vfs-stat", fd };
|
|
12135
12540
|
if (!at.orphan)
|
|
12136
12541
|
return { fd: yield openRequest(at.path, { ...o, create: false }), file };
|
|
12542
|
+
const wantWrite = o.write === true || o.append === true || o.truncate === true;
|
|
12543
|
+
if (wantWrite && info.access === "read") throw new JsCallError("EBADF", abs);
|
|
12544
|
+
if (!wantWrite && info.access === "write") throw new JsCallError("EBADF", abs);
|
|
12137
12545
|
}
|
|
12138
12546
|
const copy2 = yield { op: "fd-dup", fd, min: 3 };
|
|
12139
12547
|
if (file && o.truncate) {
|
|
@@ -12439,11 +12847,18 @@ function plain(status2, text) {
|
|
|
12439
12847
|
function local2(url) {
|
|
12440
12848
|
return isKernelLoopbackHost(new URL(url).hostname);
|
|
12441
12849
|
}
|
|
12850
|
+
function badPort(url) {
|
|
12851
|
+
const port2 = url.port ? Number(url.port) : 0;
|
|
12852
|
+
return port2 !== 0 && BAD_PORTS.has(port2);
|
|
12853
|
+
}
|
|
12442
12854
|
function rewrite(hop, status2, location) {
|
|
12443
12855
|
const next2 = new URL(location, hop.url);
|
|
12444
12856
|
if (next2.protocol !== "http:" && next2.protocol !== "https:") {
|
|
12445
12857
|
throw failed3(new JsCallError("EPROTONOSUPPORT", next2.protocol));
|
|
12446
12858
|
}
|
|
12859
|
+
if (badPort(next2)) {
|
|
12860
|
+
throw failed3(new JsCallError("EACCES", `bad port: ${next2.href}`));
|
|
12861
|
+
}
|
|
12447
12862
|
if (local2(next2.href) && !local2(hop.url)) {
|
|
12448
12863
|
const from = new URL(hop.url).origin;
|
|
12449
12864
|
throw failed3(
|
|
@@ -12729,6 +13144,9 @@ function fetchOp(kernel) {
|
|
|
12729
13144
|
if (protocol !== "http:" && protocol !== "https:") {
|
|
12730
13145
|
throw failed3(new JsCallError("EPROTONOSUPPORT", protocol));
|
|
12731
13146
|
}
|
|
13147
|
+
if (badPort(new URL(request.url))) {
|
|
13148
|
+
throw failed3(new JsCallError("EACCES", `bad port: ${request.url}`));
|
|
13149
|
+
}
|
|
12732
13150
|
let known = await traitsAt(request.url);
|
|
12733
13151
|
if (!known.manualRedirects && request.redirect !== "follow") {
|
|
12734
13152
|
throw failed3(new JsCallError("ENOTSUP", `redirect: ${request.redirect}`));
|
|
@@ -12759,7 +13177,7 @@ function fetchOp(kernel) {
|
|
|
12759
13177
|
}
|
|
12760
13178
|
};
|
|
12761
13179
|
}
|
|
12762
|
-
var CHUNK2, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
|
|
13180
|
+
var CHUNK2, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, BAD_PORTS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
|
|
12763
13181
|
var init_js_fetch = __esm({
|
|
12764
13182
|
"src/process/js/js-fetch.ts"() {
|
|
12765
13183
|
"use strict";
|
|
@@ -12778,6 +13196,89 @@ var init_js_fetch = __esm({
|
|
|
12778
13196
|
]);
|
|
12779
13197
|
DECODED = /* @__PURE__ */ new Set(["gzip", "x-gzip", "deflate"]);
|
|
12780
13198
|
CREDENTIALS = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2"]);
|
|
13199
|
+
BAD_PORTS = /* @__PURE__ */ new Set([
|
|
13200
|
+
1,
|
|
13201
|
+
7,
|
|
13202
|
+
9,
|
|
13203
|
+
11,
|
|
13204
|
+
13,
|
|
13205
|
+
15,
|
|
13206
|
+
17,
|
|
13207
|
+
19,
|
|
13208
|
+
20,
|
|
13209
|
+
21,
|
|
13210
|
+
22,
|
|
13211
|
+
23,
|
|
13212
|
+
25,
|
|
13213
|
+
37,
|
|
13214
|
+
42,
|
|
13215
|
+
43,
|
|
13216
|
+
53,
|
|
13217
|
+
69,
|
|
13218
|
+
77,
|
|
13219
|
+
79,
|
|
13220
|
+
87,
|
|
13221
|
+
95,
|
|
13222
|
+
101,
|
|
13223
|
+
102,
|
|
13224
|
+
103,
|
|
13225
|
+
104,
|
|
13226
|
+
109,
|
|
13227
|
+
110,
|
|
13228
|
+
111,
|
|
13229
|
+
113,
|
|
13230
|
+
115,
|
|
13231
|
+
117,
|
|
13232
|
+
119,
|
|
13233
|
+
123,
|
|
13234
|
+
135,
|
|
13235
|
+
137,
|
|
13236
|
+
139,
|
|
13237
|
+
143,
|
|
13238
|
+
161,
|
|
13239
|
+
179,
|
|
13240
|
+
389,
|
|
13241
|
+
427,
|
|
13242
|
+
465,
|
|
13243
|
+
512,
|
|
13244
|
+
513,
|
|
13245
|
+
514,
|
|
13246
|
+
515,
|
|
13247
|
+
526,
|
|
13248
|
+
530,
|
|
13249
|
+
531,
|
|
13250
|
+
532,
|
|
13251
|
+
540,
|
|
13252
|
+
548,
|
|
13253
|
+
554,
|
|
13254
|
+
556,
|
|
13255
|
+
563,
|
|
13256
|
+
587,
|
|
13257
|
+
601,
|
|
13258
|
+
636,
|
|
13259
|
+
989,
|
|
13260
|
+
990,
|
|
13261
|
+
993,
|
|
13262
|
+
995,
|
|
13263
|
+
1719,
|
|
13264
|
+
1720,
|
|
13265
|
+
1723,
|
|
13266
|
+
2049,
|
|
13267
|
+
3659,
|
|
13268
|
+
4045,
|
|
13269
|
+
4190,
|
|
13270
|
+
5060,
|
|
13271
|
+
5061,
|
|
13272
|
+
6e3,
|
|
13273
|
+
6566,
|
|
13274
|
+
6665,
|
|
13275
|
+
6666,
|
|
13276
|
+
6667,
|
|
13277
|
+
6668,
|
|
13278
|
+
6669,
|
|
13279
|
+
6697,
|
|
13280
|
+
10080
|
|
13281
|
+
]);
|
|
12781
13282
|
OVER = /* @__PURE__ */ Symbol("over");
|
|
12782
13283
|
TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
12783
13284
|
QUOTABLE = /^[\t\x20-\x7e\x80-\xff]*$/;
|
|
@@ -13153,6 +13654,24 @@ function laneOf(lane) {
|
|
|
13153
13654
|
}
|
|
13154
13655
|
function syncOps(kernel, shared) {
|
|
13155
13656
|
const { infos, handles, resolve } = shared;
|
|
13657
|
+
const tryDevSync = (abs) => {
|
|
13658
|
+
try {
|
|
13659
|
+
const resolved2 = physicalPath(
|
|
13660
|
+
{
|
|
13661
|
+
lstat(p) {
|
|
13662
|
+
return parseSyncFsStat(kernel.json({ op: "lstat", path: p })) ?? {};
|
|
13663
|
+
},
|
|
13664
|
+
readlink(p) {
|
|
13665
|
+
return String(kernel.json({ op: "readlink", path: p }));
|
|
13666
|
+
}
|
|
13667
|
+
},
|
|
13668
|
+
abs
|
|
13669
|
+
);
|
|
13670
|
+
return resolved2 !== abs && inDev(resolved2) ? resolved2 : void 0;
|
|
13671
|
+
} catch {
|
|
13672
|
+
return void 0;
|
|
13673
|
+
}
|
|
13674
|
+
};
|
|
13156
13675
|
const info = (fd) => {
|
|
13157
13676
|
const known = infos.get(fd);
|
|
13158
13677
|
if (known) return known;
|
|
@@ -13185,10 +13704,17 @@ function syncOps(kernel, shared) {
|
|
|
13185
13704
|
const statOf = (op, path) => {
|
|
13186
13705
|
const abs = resolve(path);
|
|
13187
13706
|
if (inDev(abs)) return devSync(kernel, devStat(abs, op === "stat"));
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13707
|
+
try {
|
|
13708
|
+
kernel.call({ op: "fd-path-flush", path: abs });
|
|
13709
|
+
const s = parseSyncFsStat(kernel.json({ op, path: abs }));
|
|
13710
|
+
if (!s) throw new JsCallError("EIO", op);
|
|
13711
|
+
return s;
|
|
13712
|
+
} catch (err) {
|
|
13713
|
+
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
13714
|
+
const devPath = tryDevSync(abs);
|
|
13715
|
+
if (!devPath) throw err;
|
|
13716
|
+
return devSync(kernel, devStat(devPath, op === "stat"));
|
|
13717
|
+
}
|
|
13192
13718
|
};
|
|
13193
13719
|
const openDev2 = (abs, options) => {
|
|
13194
13720
|
const { fd, file, ...access } = devSync(kernel, devOpen(abs, options));
|
|
@@ -13208,27 +13734,34 @@ function syncOps(kernel, shared) {
|
|
|
13208
13734
|
const open = (path, options = {}) => {
|
|
13209
13735
|
const abs = resolve(path);
|
|
13210
13736
|
if (inDev(abs)) return openDev2(abs, options);
|
|
13211
|
-
let existing;
|
|
13212
|
-
try {
|
|
13213
|
-
existing = statOf(isExclusive(options) ? "lstat" : "stat", abs);
|
|
13214
|
-
} catch (err) {
|
|
13215
|
-
existing = absent(err);
|
|
13216
|
-
}
|
|
13217
|
-
checkOpen(abs, options, existing);
|
|
13218
|
-
const fd = kernel.json(openRequest(abs, options));
|
|
13219
13737
|
try {
|
|
13220
|
-
|
|
13738
|
+
let existing;
|
|
13739
|
+
try {
|
|
13740
|
+
existing = statOf(isExclusive(options) ? "lstat" : "stat", abs);
|
|
13741
|
+
} catch (err) {
|
|
13742
|
+
existing = absent(err);
|
|
13743
|
+
}
|
|
13744
|
+
checkOpen(abs, options, existing);
|
|
13745
|
+
const fd = kernel.json(openRequest(abs, options));
|
|
13746
|
+
try {
|
|
13747
|
+
kernel.call({ op: "fd-vfs-stat", fd });
|
|
13748
|
+
} catch (err) {
|
|
13749
|
+
kernel.raw({ op: "fd-close", fd });
|
|
13750
|
+
throw err;
|
|
13751
|
+
}
|
|
13752
|
+
infos.set(fd, { kind: "file" });
|
|
13753
|
+
const handle = syncFile(kernel, fd, abs, options.append === true, () => {
|
|
13754
|
+
infos.delete(fd);
|
|
13755
|
+
handles.delete(fd);
|
|
13756
|
+
});
|
|
13757
|
+
handles.set(fd, handle.invalidate);
|
|
13758
|
+
return handle.file;
|
|
13221
13759
|
} catch (err) {
|
|
13222
|
-
|
|
13223
|
-
|
|
13760
|
+
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
13761
|
+
const devPath = tryDevSync(abs);
|
|
13762
|
+
if (!devPath) throw err;
|
|
13763
|
+
return openDev2(devPath, options);
|
|
13224
13764
|
}
|
|
13225
|
-
infos.set(fd, { kind: "file" });
|
|
13226
|
-
const handle = syncFile(kernel, fd, abs, options.append === true, () => {
|
|
13227
|
-
infos.delete(fd);
|
|
13228
|
-
handles.delete(fd);
|
|
13229
|
-
});
|
|
13230
|
-
handles.set(fd, handle.invalidate);
|
|
13231
|
-
return handle.file;
|
|
13232
13765
|
};
|
|
13233
13766
|
return {
|
|
13234
13767
|
read: read2,
|
|
@@ -13240,7 +13773,7 @@ function syncOps(kernel, shared) {
|
|
|
13240
13773
|
kernel.call({ op: "fd-close", fd });
|
|
13241
13774
|
},
|
|
13242
13775
|
open: procOpenSync(open, kernel, { resolve, pid: shared.pid }),
|
|
13243
|
-
fs: procFsSync(syncPathOps(kernel, resolve, statOf, open), kernel, {
|
|
13776
|
+
fs: procFsSync(syncPathOps(kernel, resolve, statOf, open, tryDevSync), kernel, {
|
|
13244
13777
|
resolve,
|
|
13245
13778
|
pid: shared.pid
|
|
13246
13779
|
})
|
|
@@ -13310,14 +13843,16 @@ function syncFile(kernel, fd, path, append, forget) {
|
|
|
13310
13843
|
}
|
|
13311
13844
|
};
|
|
13312
13845
|
}
|
|
13313
|
-
function syncPathOps(kernel, resolve, statOf, open) {
|
|
13846
|
+
function syncPathOps(kernel, resolve, statOf, open, tryDev) {
|
|
13314
13847
|
return {
|
|
13315
13848
|
stat: (path) => statOf("stat", path),
|
|
13316
13849
|
lstat: (path) => statOf("lstat", path),
|
|
13317
13850
|
exists(path) {
|
|
13318
13851
|
const abs = resolve(path);
|
|
13319
13852
|
if (inDev(abs)) return devSync(kernel, devExists(abs));
|
|
13320
|
-
|
|
13853
|
+
if (kernel.json({ op: "exists", path: abs }) === true) return true;
|
|
13854
|
+
const devPath = tryDev(abs);
|
|
13855
|
+
return devPath ? devSync(kernel, devExists(devPath)) : false;
|
|
13321
13856
|
},
|
|
13322
13857
|
readdir(path) {
|
|
13323
13858
|
const abs = resolve(path);
|
|
@@ -13342,15 +13877,29 @@ function syncPathOps(kernel, resolve, statOf, open) {
|
|
|
13342
13877
|
return String(kernel.json({ op: "readlink", path: abs }));
|
|
13343
13878
|
},
|
|
13344
13879
|
statfs(path) {
|
|
13345
|
-
|
|
13880
|
+
let abs = resolve(path);
|
|
13881
|
+
if (inDev(abs)) {
|
|
13882
|
+
try {
|
|
13883
|
+
const target = devSync(kernel, devResolveTarget(abs));
|
|
13884
|
+
if (target?.startsWith("/")) abs = target;
|
|
13885
|
+
} catch {
|
|
13886
|
+
}
|
|
13887
|
+
}
|
|
13346
13888
|
statOf("stat", abs);
|
|
13347
13889
|
return statFsOf(kernel.json({ op: "statfs", path: abs }));
|
|
13348
13890
|
},
|
|
13349
13891
|
readFile(path) {
|
|
13350
13892
|
const abs = resolve(path);
|
|
13351
13893
|
if (inDev(abs)) return readWholeSync(open(abs));
|
|
13352
|
-
|
|
13353
|
-
|
|
13894
|
+
try {
|
|
13895
|
+
kernel.call({ op: "fd-path-flush", path: abs });
|
|
13896
|
+
return kernel.bytes({ op: "read", path: abs });
|
|
13897
|
+
} catch (err) {
|
|
13898
|
+
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
13899
|
+
const devPath = tryDev(abs);
|
|
13900
|
+
if (!devPath) throw err;
|
|
13901
|
+
return readWholeSync(open(devPath));
|
|
13902
|
+
}
|
|
13354
13903
|
},
|
|
13355
13904
|
writeFile(path, data, options) {
|
|
13356
13905
|
const mode = options?.mode;
|
|
@@ -13372,6 +13921,7 @@ var encoder3, noLane, JsSyncKernel;
|
|
|
13372
13921
|
var init_js_sync = __esm({
|
|
13373
13922
|
"src/process/js/js-sync.ts"() {
|
|
13374
13923
|
"use strict";
|
|
13924
|
+
init_physical_path();
|
|
13375
13925
|
init_signals();
|
|
13376
13926
|
init_sync_fs_wire();
|
|
13377
13927
|
init_sync_sab_bridge();
|
|
@@ -13768,6 +14318,55 @@ function readable2(read2) {
|
|
|
13768
14318
|
{ highWaterMark: 0 }
|
|
13769
14319
|
);
|
|
13770
14320
|
}
|
|
14321
|
+
async function resolveDevAsync(kernel, abs) {
|
|
14322
|
+
try {
|
|
14323
|
+
const resolved2 = await physicalPathAsync(
|
|
14324
|
+
{
|
|
14325
|
+
async lstat(p) {
|
|
14326
|
+
return parseSyncFsStat(await kernel.json({ op: "lstat", path: p })) ?? {};
|
|
14327
|
+
},
|
|
14328
|
+
async readlink(p) {
|
|
14329
|
+
return String(await kernel.json({ op: "readlink", path: p }));
|
|
14330
|
+
}
|
|
14331
|
+
},
|
|
14332
|
+
abs
|
|
14333
|
+
);
|
|
14334
|
+
return resolved2 !== abs && inDev(resolved2) ? resolved2 : void 0;
|
|
14335
|
+
} catch {
|
|
14336
|
+
return void 0;
|
|
14337
|
+
}
|
|
14338
|
+
}
|
|
14339
|
+
async function vfsStat(kernel, abs, op, tryDev) {
|
|
14340
|
+
try {
|
|
14341
|
+
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
14342
|
+
const s = parseSyncFsStat(await kernel.json({ op, path: abs }));
|
|
14343
|
+
if (!s) throw new JsCallError("EIO", op);
|
|
14344
|
+
return s;
|
|
14345
|
+
} catch (err) {
|
|
14346
|
+
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
14347
|
+
const devPath = await tryDev(abs);
|
|
14348
|
+
if (!devPath) throw err;
|
|
14349
|
+
return devAsync(kernel, devStat(devPath, op === "stat"));
|
|
14350
|
+
}
|
|
14351
|
+
}
|
|
14352
|
+
async function vfsOpen(kernel, abs, options, statOf, infos, handles) {
|
|
14353
|
+
const existing = await statOf(isExclusive(options) ? "lstat" : "stat", abs).catch(absent);
|
|
14354
|
+
checkOpen(abs, options, existing);
|
|
14355
|
+
const fd = await kernel.json(openRequest(abs, options));
|
|
14356
|
+
try {
|
|
14357
|
+
await kernel.call({ op: "fd-vfs-stat", fd });
|
|
14358
|
+
} catch (err) {
|
|
14359
|
+
await kernel.raw({ op: "fd-close", fd });
|
|
14360
|
+
throw err;
|
|
14361
|
+
}
|
|
14362
|
+
infos.set(fd, { kind: "file" });
|
|
14363
|
+
const handle = fileHandle(kernel, fd, abs, options.append === true, () => {
|
|
14364
|
+
infos.delete(fd);
|
|
14365
|
+
handles.delete(fd);
|
|
14366
|
+
});
|
|
14367
|
+
handles.set(fd, handle.invalidate);
|
|
14368
|
+
return handle.file;
|
|
14369
|
+
}
|
|
13771
14370
|
function createContext(o) {
|
|
13772
14371
|
const { kernel } = o;
|
|
13773
14372
|
const infos = /* @__PURE__ */ new Map();
|
|
@@ -13775,6 +14374,7 @@ function createContext(o) {
|
|
|
13775
14374
|
const pending = /* @__PURE__ */ new Set();
|
|
13776
14375
|
const random = o.random ?? ((bytes) => void crypto.getRandomValues(bytes));
|
|
13777
14376
|
const resolve = (path) => resolvePath(o.cwd, path);
|
|
14377
|
+
const tryDev = (abs) => resolveDevAsync(kernel, abs);
|
|
13778
14378
|
let exiting;
|
|
13779
14379
|
const exit = (code2 = 0) => {
|
|
13780
14380
|
exiting ??= code2;
|
|
@@ -13817,32 +14417,25 @@ function createContext(o) {
|
|
|
13817
14417
|
const statOf = async (op, path) => {
|
|
13818
14418
|
const abs = resolve(path);
|
|
13819
14419
|
if (inDev(abs)) return devAsync(kernel, devStat(abs, op === "stat"));
|
|
13820
|
-
|
|
13821
|
-
const s = parseSyncFsStat(await kernel.json({ op, path: abs }));
|
|
13822
|
-
if (!s) throw new JsCallError("EIO", op);
|
|
13823
|
-
return s;
|
|
14420
|
+
return vfsStat(kernel, abs, op, tryDev);
|
|
13824
14421
|
};
|
|
14422
|
+
const devIo = { infos, handles, read: read2, write: writeAll };
|
|
13825
14423
|
const open = async (path, options = {}) => {
|
|
13826
14424
|
const abs = resolve(path);
|
|
13827
|
-
if (inDev(abs)) return openDev(kernel, abs, options,
|
|
13828
|
-
const existing = await statOf(isExclusive(options) ? "lstat" : "stat", abs).catch(absent);
|
|
13829
|
-
checkOpen(abs, options, existing);
|
|
13830
|
-
const fd = await kernel.json(openRequest(abs, options));
|
|
14425
|
+
if (inDev(abs)) return openDev(kernel, abs, options, devIo);
|
|
13831
14426
|
try {
|
|
13832
|
-
await kernel
|
|
14427
|
+
return await vfsOpen(kernel, abs, options, statOf, infos, handles);
|
|
13833
14428
|
} catch (err) {
|
|
13834
|
-
|
|
13835
|
-
|
|
14429
|
+
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
14430
|
+
const devPath = await tryDev(abs);
|
|
14431
|
+
if (!devPath) throw err;
|
|
14432
|
+
return openDev(kernel, devPath, options, devIo);
|
|
13836
14433
|
}
|
|
13837
|
-
infos.set(fd, { kind: "file" });
|
|
13838
|
-
const handle = fileHandle(kernel, fd, abs, options.append === true, () => {
|
|
13839
|
-
infos.delete(fd);
|
|
13840
|
-
handles.delete(fd);
|
|
13841
|
-
});
|
|
13842
|
-
handles.set(fd, handle.invalidate);
|
|
13843
|
-
return handle.file;
|
|
13844
14434
|
};
|
|
13845
|
-
const fs = procFsAsync(pathOps(kernel, resolve, statOf, open), kernel, {
|
|
14435
|
+
const fs = procFsAsync(pathOps(kernel, resolve, statOf, open, tryDev), kernel, {
|
|
14436
|
+
resolve,
|
|
14437
|
+
pid: o.pid
|
|
14438
|
+
});
|
|
13846
14439
|
const lane = o.lane ?? laneOf(void 0);
|
|
13847
14440
|
if (o.lane && o.lane !== noLane) kernel.syncLane = o.lane;
|
|
13848
14441
|
const syncKernel = new JsSyncKernel(lane, kernel, unwind);
|
|
@@ -14038,14 +14631,16 @@ async function sendSome(kernel, fd, body, signal) {
|
|
|
14038
14631
|
await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
|
|
14039
14632
|
}
|
|
14040
14633
|
}
|
|
14041
|
-
function pathOps(kernel, resolve, statOf, open) {
|
|
14634
|
+
function pathOps(kernel, resolve, statOf, open, tryDev) {
|
|
14042
14635
|
return {
|
|
14043
14636
|
stat: (path) => statOf("stat", path),
|
|
14044
14637
|
lstat: (path) => statOf("lstat", path),
|
|
14045
14638
|
async exists(path) {
|
|
14046
14639
|
const abs = resolve(path);
|
|
14047
14640
|
if (inDev(abs)) return devAsync(kernel, devExists(abs));
|
|
14048
|
-
|
|
14641
|
+
if (await kernel.json({ op: "exists", path: abs }) === true) return true;
|
|
14642
|
+
const devPath = await tryDev(abs);
|
|
14643
|
+
return devPath ? devAsync(kernel, devExists(devPath)) : false;
|
|
14049
14644
|
},
|
|
14050
14645
|
async readdir(path) {
|
|
14051
14646
|
const abs = resolve(path);
|
|
@@ -14070,15 +14665,26 @@ function pathOps(kernel, resolve, statOf, open) {
|
|
|
14070
14665
|
return String(await kernel.json({ op: "readlink", path: abs }));
|
|
14071
14666
|
},
|
|
14072
14667
|
async statfs(path) {
|
|
14073
|
-
|
|
14668
|
+
let abs = resolve(path);
|
|
14669
|
+
if (inDev(abs)) {
|
|
14670
|
+
const target = await devAsync(kernel, devResolveTarget(abs)).catch(() => void 0);
|
|
14671
|
+
if (target?.startsWith("/")) abs = target;
|
|
14672
|
+
}
|
|
14074
14673
|
await statOf("stat", abs);
|
|
14075
14674
|
return statFsOf(await kernel.json({ op: "statfs", path: abs }));
|
|
14076
14675
|
},
|
|
14077
14676
|
async readFile(path) {
|
|
14078
14677
|
const abs = resolve(path);
|
|
14079
14678
|
if (inDev(abs)) return readWhole(await open(abs));
|
|
14080
|
-
|
|
14081
|
-
|
|
14679
|
+
try {
|
|
14680
|
+
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
14681
|
+
return await kernel.bytes({ op: "read", path: abs });
|
|
14682
|
+
} catch (err) {
|
|
14683
|
+
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
14684
|
+
const devPath = await tryDev(abs);
|
|
14685
|
+
if (!devPath) throw err;
|
|
14686
|
+
return readWhole(await open(devPath));
|
|
14687
|
+
}
|
|
14082
14688
|
},
|
|
14083
14689
|
async writeFile(path, data, options) {
|
|
14084
14690
|
const mode = options?.mode;
|
|
@@ -14100,6 +14706,7 @@ var KERNEL_INFO, JsExit, encoder4;
|
|
|
14100
14706
|
var init_js_context = __esm({
|
|
14101
14707
|
"src/process/js/js-context.ts"() {
|
|
14102
14708
|
"use strict";
|
|
14709
|
+
init_physical_path();
|
|
14103
14710
|
init_signals();
|
|
14104
14711
|
init_sync_fs_wire();
|
|
14105
14712
|
init_version();
|