@ai-ecoverse/slicc-kernel 1.73.2 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -857,6 +857,227 @@ var init_sync_fs_wire = __esm({
857
857
  }
858
858
  });
859
859
 
860
+ // src/realm/sync-sab-bridge.ts
861
+ function syncCallCount() {
862
+ return calls;
863
+ }
864
+ function createSyncSabTransport(sab, port2, deps = {}) {
865
+ const views = sabViews(sab);
866
+ const { header, window } = views;
867
+ const wait2 = deps.wait ?? ((a, i, v, t) => rawWait(a, i, v, t));
868
+ const now = deps.now ?? (() => performance.now());
869
+ let seq = 0;
870
+ function awaitReady(id, deadline, label) {
871
+ for (; ; ) {
872
+ const published = Atomics.load(header, SAB_I_PUB);
873
+ if (Atomics.load(header, SAB_I_STATE) === SAB_STATE_READY && Atomics.load(header, SAB_I_SEQ) === id) {
874
+ return;
875
+ }
876
+ const remaining = deadline - now();
877
+ if (remaining <= 0) throw syncError("ETIMEDOUT", label);
878
+ wait2(header, SAB_I_PUB, published, remaining);
879
+ }
880
+ }
881
+ return {
882
+ call(req, timeoutMs, label, transfer = []) {
883
+ if (deps.memory) publishMemory(sab, deps.memory());
884
+ const id = ++seq;
885
+ calls += Number(!PATH_OPS.has(req.op));
886
+ const deadline = now() + timeoutMs;
887
+ let out = null;
888
+ let status2 = 0;
889
+ let offset = 0;
890
+ Atomics.store(header, SAB_I_REQ, id);
891
+ try {
892
+ for (; ; ) {
893
+ Atomics.store(header, SAB_I_STATE, SAB_STATE_PENDING);
894
+ const msg = offset === 0 ? { type: SYNC_SAB_REQ_MSG, id, req } : { type: SYNC_SAB_NEXT_MSG, id, offset };
895
+ try {
896
+ if (offset === 0 && transfer.length > 0) port2.postMessage(msg, transfer);
897
+ else port2.postMessage(msg);
898
+ } catch {
899
+ throw syncError("EIO", label);
900
+ }
901
+ awaitReady(id, deadline, label);
902
+ const total = loadU53(header, SAB_I_TOTAL, SAB_I_TOTAL_HI);
903
+ const chunk = Atomics.load(header, SAB_I_CHUNK);
904
+ const at = loadU53(header, SAB_I_OFFSET, SAB_I_OFFSET_HI);
905
+ if (at !== offset || chunk < 0 || total < 0 || offset + chunk > total) {
906
+ throw syncError("EIO", label);
907
+ }
908
+ if (out === null) {
909
+ status2 = Atomics.load(header, SAB_I_STATUS);
910
+ out = new Uint8Array(total);
911
+ }
912
+ out.set(window.subarray(0, chunk), offset);
913
+ offset += chunk;
914
+ if (offset >= total) break;
915
+ if (chunk === 0) throw syncError("EIO", label);
916
+ }
917
+ } finally {
918
+ Atomics.store(header, SAB_I_REQ, 0);
919
+ Atomics.store(header, SAB_I_STATE, SAB_STATE_IDLE);
920
+ }
921
+ return decodeSabResult(status2, out);
922
+ }
923
+ };
924
+ }
925
+ function errnoError(code2, path) {
926
+ return syncError(code2, `sync-sab bridge, '${path}'`);
927
+ }
928
+ function createSyncFsSabBridge(transport, opts = {}) {
929
+ const timeoutMs = opts.timeoutMs ?? SYNC_FS_REQUEST_TIMEOUT_MS;
930
+ let identity = {};
931
+ let last = null;
932
+ function run(req, path, transfer) {
933
+ last = null;
934
+ const result = transport.call(req, timeoutMs, `sync-sab bridge, '${path}'`, transfer);
935
+ if (!result.ok) throw errnoError(result.errno, path);
936
+ return result;
937
+ }
938
+ function bytes(req, path) {
939
+ const r = run(req, path);
940
+ if (r.ok && r.kind === "bytes") return r.bytes;
941
+ throw errnoError("EIO", path);
942
+ }
943
+ function json2(req, path) {
944
+ const r = run(req, path);
945
+ if (r.ok && r.kind === "json") return r.json;
946
+ throw errnoError("EIO", path);
947
+ }
948
+ const changing = (req, path, transfer) => {
949
+ const r = run({ ...req, ...identity }, path, transfer);
950
+ if (r.ok && r.kind === "json") last = parseSyncFsStat(r.json);
951
+ };
952
+ const io = (id) => ({
953
+ readFile: (path) => bytes({ op: "read", path, ...id }, path),
954
+ writeFile: (path, data, open) => {
955
+ changing({ op: "write", path, body: data, ...open ? { mode: 1 } : {}, ...id }, path);
956
+ },
957
+ pread: (path, offset, length, version) => bytes({ op: "pread", path, offset, length, ...version ? { version } : {}, ...id }, path),
958
+ pwrite: (path, offset, body, transfer) => {
959
+ const whole = body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
960
+ const owned = transfer && whole && body.buffer instanceof ArrayBuffer;
961
+ const transferred = owned ? [body.buffer] : [];
962
+ changing({ op: "pwrite", path, offset, body, ...id }, path, transferred);
963
+ },
964
+ truncate: (path, length) => {
965
+ changing({ op: "truncate", path, length, ...id }, path);
966
+ }
967
+ });
968
+ return {
969
+ ...io({}),
970
+ pinned: (handle) => io({ handle }),
971
+ kept: (handle) => json2({ op: "kept", path: "/", handle }, "/") === true,
972
+ keptStat: (handle) => {
973
+ const s = parseSyncFsStat(json2({ op: "stat", path: "/", handle }, "/"));
974
+ if (!s) throw errnoError("EIO", "/");
975
+ return s;
976
+ },
977
+ stat: (path) => {
978
+ const s = parseSyncFsStat(json2({ op: "stat", path }, path));
979
+ if (!s) throw errnoError("EIO", path);
980
+ return s;
981
+ },
982
+ lstat: (path) => {
983
+ const s = parseSyncFsStat(json2({ op: "lstat", path }, path));
984
+ if (!s) throw errnoError("EIO", path);
985
+ return s;
986
+ },
987
+ readdir: (path) => {
988
+ const list = json2({ op: "readdir", path }, path);
989
+ if (!Array.isArray(list) || !list.every((s) => typeof s === "string")) {
990
+ throw errnoError("EIO", path);
991
+ }
992
+ return list;
993
+ },
994
+ readdirStat: (path) => {
995
+ const list = json2({ op: "readdir-stat", path }, path);
996
+ if (!Array.isArray(list)) throw errnoError("EIO", path);
997
+ return list.map((entry) => {
998
+ if (!Array.isArray(entry) || typeof entry[0] !== "string") throw errnoError("EIO", path);
999
+ if (entry[1] === null) return [entry[0], null];
1000
+ const stat = parseSyncFsStat(entry[1]);
1001
+ if (!stat) throw errnoError("EIO", path);
1002
+ return [entry[0], stat];
1003
+ });
1004
+ },
1005
+ exists: (path) => {
1006
+ const v = json2({ op: "exists", path }, path);
1007
+ if (typeof v !== "boolean") throw errnoError("EIO", path);
1008
+ return v;
1009
+ },
1010
+ mkdir: (path, mode) => {
1011
+ run({ op: "mkdir", path, exclusive: true, ...mode !== void 0 ? { mode } : {} }, path);
1012
+ },
1013
+ rm: (path) => {
1014
+ run({ op: "rm", path }, path);
1015
+ },
1016
+ rename: (from, to) => {
1017
+ run({ op: "rename", path: from, arg2: to }, from);
1018
+ },
1019
+ link: (from, to, follow2) => {
1020
+ run({ op: "link", path: from, arg2: to, ...follow2 ? { mode: 1 } : {} }, from);
1021
+ },
1022
+ unlink: (path) => {
1023
+ run({ op: "unlink", path }, path);
1024
+ },
1025
+ rmdir: (path) => {
1026
+ run({ op: "rmdir", path }, path);
1027
+ },
1028
+ symlink: (target, linkPath) => {
1029
+ run({ op: "symlink", path: linkPath, arg2: target }, linkPath);
1030
+ },
1031
+ readlink: (path) => {
1032
+ const target = json2({ op: "readlink", path }, path);
1033
+ if (typeof target !== "string") throw errnoError("EIO", path);
1034
+ return target;
1035
+ },
1036
+ chmod: (path, mode) => {
1037
+ changing({ op: "chmod", path, mode }, path);
1038
+ },
1039
+ utimes: (path, atimeMs, mtimeMs, now) => {
1040
+ changing({ op: "utimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
1041
+ },
1042
+ identify: () => {
1043
+ identity = { identity: true };
1044
+ },
1045
+ identified: () => last,
1046
+ lutimes: (path, atimeMs, mtimeMs, now) => {
1047
+ run({ op: "lutimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
1048
+ },
1049
+ create: (path, mode) => {
1050
+ run({ op: "create", path, ...mode !== void 0 ? { mode } : {} }, path);
1051
+ },
1052
+ chown: (path, uid, gid, follow2) => {
1053
+ const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
1054
+ changing({ op: follow2 ? "chown" : "lchown", path, ...ids }, path);
1055
+ },
1056
+ ...opts.owners ? { owners: true } : {},
1057
+ access: (path, mode, kind = "access", nofollow) => {
1058
+ run({ op: "access", path, mode, arg2: kind, ...nofollow ? { nofollow } : {} }, path);
1059
+ },
1060
+ hold: (path, held, open, handle, want = 0) => {
1061
+ const mode = (held ? 1 : 0) | (open ? 2 : 0);
1062
+ if (mode === 3) return json2({ op: "hold", path, mode: mode | want }, path);
1063
+ run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
1064
+ return void 0;
1065
+ },
1066
+ statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path))
1067
+ };
1068
+ }
1069
+ var PATH_OPS, calls;
1070
+ var init_sync_sab_bridge = __esm({
1071
+ "src/realm/sync-sab-bridge.ts"() {
1072
+ "use strict";
1073
+ init_cpu_clock();
1074
+ init_sync_fs_wire();
1075
+ init_sync_sab_wire();
1076
+ PATH_OPS = new Set(SYNC_FS_OPS);
1077
+ calls = 0;
1078
+ }
1079
+ });
1080
+
860
1081
  // src/realm/live-vfs-fs.ts
861
1082
  function toErrno(Fs, err) {
862
1083
  if (err?.errno !== void 0 && err instanceof Fs.ErrnoError) {
@@ -898,6 +1119,9 @@ function refusal(err) {
898
1119
  const code2 = err?.code;
899
1120
  return code2 === "EACCES" || code2 === "EPERM";
900
1121
  }
1122
+ function cachedStat(s, dir) {
1123
+ return s.stat !== void 0 && (!dir || s.statAt === syncCallCount());
1124
+ }
901
1125
  function linkedStates(bridgeOf) {
902
1126
  const opens = /* @__PURE__ */ new Map();
903
1127
  const byId = /* @__PURE__ */ new Map();
@@ -980,7 +1204,8 @@ function createHelpers(Fs, ops) {
980
1204
  }
981
1205
  }
982
1206
  function freshState(stat) {
983
- return { ...stat ? { stat } : {}, len: 0, loaded: false, dirty: false, openCount: 0 };
1207
+ const statAt = syncCallCount();
1208
+ return { ...stat ? { stat, statAt } : {}, len: 0, loaded: false, dirty: false, openCount: 0 };
984
1209
  }
985
1210
  function makeNode(parent, name2, st) {
986
1211
  const node = Fs.createNode(parent, name2, modeFromStat(st), 0);
@@ -994,9 +1219,9 @@ function createHelpers(Fs, ops) {
994
1219
  const size = node.live.ranged?.size() ?? node.live.len;
995
1220
  return { ...node.live.stat, size };
996
1221
  }
997
- if (!node.live.stat) {
1222
+ if (!cachedStat(node.live, Fs.isDir(node.mode))) {
998
1223
  const st = call2(() => bridgeOf(node).lstat(liveNodePath(linked.holder(node))));
999
- node.live.stat = st;
1224
+ Object.assign(node.live, { stat: st, statAt: syncCallCount() });
1000
1225
  node.mode = modeFromStat(st);
1001
1226
  }
1002
1227
  return node.live.stat;
@@ -1145,8 +1370,9 @@ function createNodeOps(h) {
1145
1370
  flushNode(node);
1146
1371
  metadataCall(() => bridgeOf(node).utimes(path, atime, mtime, now));
1147
1372
  };
1373
+ const stamped = typeof Fs.doSetAttr !== "function";
1148
1374
  const timesOf = (node, attr2) => {
1149
- const mtime = toMs(attr2.mtime) ?? attr2.timestamp;
1375
+ const mtime = toMs(attr2.mtime) ?? (stamped ? attr2.timestamp : void 0);
1150
1376
  const atime = toMs(attr2.atime);
1151
1377
  if (mtime !== void 0 && attr2.atime !== null) return [atime ?? mtime, mtime];
1152
1378
  if (atime === void 0 && mtime === void 0) return void 0;
@@ -1155,8 +1381,10 @@ function createNodeOps(h) {
1155
1381
  };
1156
1382
  return {
1157
1383
  getattr(node) {
1158
- const st = statOf(node);
1159
1384
  const owned = bridgeOf(node).owners === true;
1385
+ if (owned && Fs.isLink(node.mode) && statOf(node).uid === void 0)
1386
+ node.live.stat = void 0;
1387
+ const st = statOf(node);
1160
1388
  const s = node.live;
1161
1389
  const size = Fs.isDir(node.mode) ? 4096 : s.ranged?.size() ?? (s.loaded ? s.len : st.size);
1162
1390
  const mtime = new Date(st.mtimeMs ?? 0);
@@ -1683,6 +1911,7 @@ var init_live_vfs_fs = __esm({
1683
1911
  init_types();
1684
1912
  init_wasi_errno();
1685
1913
  init_sync_fs_wire();
1914
+ init_sync_sab_bridge();
1686
1915
  S_IFDIR = 16384;
1687
1916
  S_IFREG = 32768;
1688
1917
  S_IFLNK = 40960;
@@ -1746,220 +1975,6 @@ var init_emscripten_vfs_hook = __esm({
1746
1975
  }
1747
1976
  });
1748
1977
 
1749
- // src/realm/sync-sab-bridge.ts
1750
- function createSyncSabTransport(sab, port2, deps = {}) {
1751
- const views = sabViews(sab);
1752
- const { header, window } = views;
1753
- const wait2 = deps.wait ?? ((a, i, v, t) => rawWait(a, i, v, t));
1754
- const now = deps.now ?? (() => performance.now());
1755
- let seq = 0;
1756
- function awaitReady(id, deadline, label) {
1757
- for (; ; ) {
1758
- const published = Atomics.load(header, SAB_I_PUB);
1759
- if (Atomics.load(header, SAB_I_STATE) === SAB_STATE_READY && Atomics.load(header, SAB_I_SEQ) === id) {
1760
- return;
1761
- }
1762
- const remaining = deadline - now();
1763
- if (remaining <= 0) throw syncError("ETIMEDOUT", label);
1764
- wait2(header, SAB_I_PUB, published, remaining);
1765
- }
1766
- }
1767
- return {
1768
- call(req, timeoutMs, label, transfer = []) {
1769
- if (deps.memory) publishMemory(sab, deps.memory());
1770
- const id = ++seq;
1771
- const deadline = now() + timeoutMs;
1772
- let out = null;
1773
- let status2 = 0;
1774
- let offset = 0;
1775
- Atomics.store(header, SAB_I_REQ, id);
1776
- try {
1777
- for (; ; ) {
1778
- Atomics.store(header, SAB_I_STATE, SAB_STATE_PENDING);
1779
- const msg = offset === 0 ? { type: SYNC_SAB_REQ_MSG, id, req } : { type: SYNC_SAB_NEXT_MSG, id, offset };
1780
- try {
1781
- if (offset === 0 && transfer.length > 0) port2.postMessage(msg, transfer);
1782
- else port2.postMessage(msg);
1783
- } catch {
1784
- throw syncError("EIO", label);
1785
- }
1786
- awaitReady(id, deadline, label);
1787
- const total = loadU53(header, SAB_I_TOTAL, SAB_I_TOTAL_HI);
1788
- const chunk = Atomics.load(header, SAB_I_CHUNK);
1789
- const at = loadU53(header, SAB_I_OFFSET, SAB_I_OFFSET_HI);
1790
- if (at !== offset || chunk < 0 || total < 0 || offset + chunk > total) {
1791
- throw syncError("EIO", label);
1792
- }
1793
- if (out === null) {
1794
- status2 = Atomics.load(header, SAB_I_STATUS);
1795
- out = new Uint8Array(total);
1796
- }
1797
- out.set(window.subarray(0, chunk), offset);
1798
- offset += chunk;
1799
- if (offset >= total) break;
1800
- if (chunk === 0) throw syncError("EIO", label);
1801
- }
1802
- } finally {
1803
- Atomics.store(header, SAB_I_REQ, 0);
1804
- Atomics.store(header, SAB_I_STATE, SAB_STATE_IDLE);
1805
- }
1806
- return decodeSabResult(status2, out);
1807
- }
1808
- };
1809
- }
1810
- function errnoError(code2, path) {
1811
- return syncError(code2, `sync-sab bridge, '${path}'`);
1812
- }
1813
- function createSyncFsSabBridge(transport, opts = {}) {
1814
- const timeoutMs = opts.timeoutMs ?? SYNC_FS_REQUEST_TIMEOUT_MS;
1815
- let identity = {};
1816
- let last = null;
1817
- function run(req, path, transfer) {
1818
- last = null;
1819
- const result = transport.call(req, timeoutMs, `sync-sab bridge, '${path}'`, transfer);
1820
- if (!result.ok) throw errnoError(result.errno, path);
1821
- return result;
1822
- }
1823
- function bytes(req, path) {
1824
- const r = run(req, path);
1825
- if (r.ok && r.kind === "bytes") return r.bytes;
1826
- throw errnoError("EIO", path);
1827
- }
1828
- function json2(req, path) {
1829
- const r = run(req, path);
1830
- if (r.ok && r.kind === "json") return r.json;
1831
- throw errnoError("EIO", path);
1832
- }
1833
- const changing = (req, path, transfer) => {
1834
- const r = run({ ...req, ...identity }, path, transfer);
1835
- if (r.ok && r.kind === "json") last = parseSyncFsStat(r.json);
1836
- };
1837
- const io = (id) => ({
1838
- readFile: (path) => bytes({ op: "read", path, ...id }, path),
1839
- writeFile: (path, data, open) => {
1840
- changing({ op: "write", path, body: data, ...open ? { mode: 1 } : {}, ...id }, path);
1841
- },
1842
- pread: (path, offset, length, version) => bytes({ op: "pread", path, offset, length, ...version ? { version } : {}, ...id }, path),
1843
- pwrite: (path, offset, body, transfer) => {
1844
- const whole = body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
1845
- const owned = transfer && whole && body.buffer instanceof ArrayBuffer;
1846
- const transferred = owned ? [body.buffer] : [];
1847
- changing({ op: "pwrite", path, offset, body, ...id }, path, transferred);
1848
- },
1849
- truncate: (path, length) => {
1850
- changing({ op: "truncate", path, length, ...id }, path);
1851
- }
1852
- });
1853
- return {
1854
- ...io({}),
1855
- pinned: (handle) => io({ handle }),
1856
- kept: (handle) => json2({ op: "kept", path: "/", handle }, "/") === true,
1857
- keptStat: (handle) => {
1858
- const s = parseSyncFsStat(json2({ op: "stat", path: "/", handle }, "/"));
1859
- if (!s) throw errnoError("EIO", "/");
1860
- return s;
1861
- },
1862
- stat: (path) => {
1863
- const s = parseSyncFsStat(json2({ op: "stat", path }, path));
1864
- if (!s) throw errnoError("EIO", path);
1865
- return s;
1866
- },
1867
- lstat: (path) => {
1868
- const s = parseSyncFsStat(json2({ op: "lstat", path }, path));
1869
- if (!s) throw errnoError("EIO", path);
1870
- return s;
1871
- },
1872
- readdir: (path) => {
1873
- const list = json2({ op: "readdir", path }, path);
1874
- if (!Array.isArray(list) || !list.every((s) => typeof s === "string")) {
1875
- throw errnoError("EIO", path);
1876
- }
1877
- return list;
1878
- },
1879
- readdirStat: (path) => {
1880
- const list = json2({ op: "readdir-stat", path }, path);
1881
- if (!Array.isArray(list)) throw errnoError("EIO", path);
1882
- return list.map((entry) => {
1883
- if (!Array.isArray(entry) || typeof entry[0] !== "string") throw errnoError("EIO", path);
1884
- if (entry[1] === null) return [entry[0], null];
1885
- const stat = parseSyncFsStat(entry[1]);
1886
- if (!stat) throw errnoError("EIO", path);
1887
- return [entry[0], stat];
1888
- });
1889
- },
1890
- exists: (path) => {
1891
- const v = json2({ op: "exists", path }, path);
1892
- if (typeof v !== "boolean") throw errnoError("EIO", path);
1893
- return v;
1894
- },
1895
- mkdir: (path, mode) => {
1896
- run({ op: "mkdir", path, exclusive: true, ...mode !== void 0 ? { mode } : {} }, path);
1897
- },
1898
- rm: (path) => {
1899
- run({ op: "rm", path }, path);
1900
- },
1901
- rename: (from, to) => {
1902
- run({ op: "rename", path: from, arg2: to }, from);
1903
- },
1904
- link: (from, to, follow2) => {
1905
- run({ op: "link", path: from, arg2: to, ...follow2 ? { mode: 1 } : {} }, from);
1906
- },
1907
- unlink: (path) => {
1908
- run({ op: "unlink", path }, path);
1909
- },
1910
- rmdir: (path) => {
1911
- run({ op: "rmdir", path }, path);
1912
- },
1913
- symlink: (target, linkPath) => {
1914
- run({ op: "symlink", path: linkPath, arg2: target }, linkPath);
1915
- },
1916
- readlink: (path) => {
1917
- const target = json2({ op: "readlink", path }, path);
1918
- if (typeof target !== "string") throw errnoError("EIO", path);
1919
- return target;
1920
- },
1921
- chmod: (path, mode) => {
1922
- changing({ op: "chmod", path, mode }, path);
1923
- },
1924
- utimes: (path, atimeMs, mtimeMs, now) => {
1925
- changing({ op: "utimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
1926
- },
1927
- identify: () => {
1928
- identity = { identity: true };
1929
- },
1930
- identified: () => last,
1931
- lutimes: (path, atimeMs, mtimeMs, now) => {
1932
- run({ op: "lutimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
1933
- },
1934
- create: (path, mode) => {
1935
- run({ op: "create", path, ...mode !== void 0 ? { mode } : {} }, path);
1936
- },
1937
- chown: (path, uid, gid, follow2) => {
1938
- const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
1939
- changing({ op: follow2 ? "chown" : "lchown", path, ...ids }, path);
1940
- },
1941
- ...opts.owners ? { owners: true } : {},
1942
- access: (path, mode, kind = "access", nofollow) => {
1943
- run({ op: "access", path, mode, arg2: kind, ...nofollow ? { nofollow } : {} }, path);
1944
- },
1945
- hold: (path, held, open, handle, want = 0) => {
1946
- const mode = (held ? 1 : 0) | (open ? 2 : 0);
1947
- if (mode === 3) return json2({ op: "hold", path, mode: mode | want }, path);
1948
- run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
1949
- return void 0;
1950
- },
1951
- statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path))
1952
- };
1953
- }
1954
- var init_sync_sab_bridge = __esm({
1955
- "src/realm/sync-sab-bridge.ts"() {
1956
- "use strict";
1957
- init_cpu_clock();
1958
- init_sync_fs_wire();
1959
- init_sync_sab_wire();
1960
- }
1961
- });
1962
-
1963
1978
  // src/process/kernel-streams.ts
1964
1979
  function isPtyPath(path) {
1965
1980
  return PTY_PATH.test(path);
@@ -11123,6 +11138,7 @@ function childOps(kernel, io, defaults) {
11123
11138
  const spawn = async (o) => {
11124
11139
  const [file] = o.argv;
11125
11140
  if (file === void 0) throw new JsCallError("EINVAL", "spawn");
11141
+ const group = groupOf(o, "spawn");
11126
11142
  const mine = [];
11127
11143
  const theirs = [];
11128
11144
  try {
@@ -11133,7 +11149,8 @@ function childOps(kernel, io, defaults) {
11133
11149
  argv: [...o.argv],
11134
11150
  env: { ...o.env ?? defaults.env },
11135
11151
  cwd: o.cwd ?? defaults.cwd,
11136
- stdio
11152
+ stdio,
11153
+ ...group
11137
11154
  });
11138
11155
  return childOf(pid, mine);
11139
11156
  } catch (err) {
@@ -11145,6 +11162,15 @@ function childOps(kernel, io, defaults) {
11145
11162
  };
11146
11163
  return { spawn, wait: wait2, kill };
11147
11164
  }
11165
+ function groupOf(o, call2) {
11166
+ const { pgid, session } = o;
11167
+ const valid = pgid === void 0 || Number.isInteger(pgid) && pgid >= 0;
11168
+ if (!valid || session !== void 0 && typeof session !== "boolean") {
11169
+ throw new JsCallError("EINVAL", call2);
11170
+ }
11171
+ if (session && pgid !== void 0) throw new JsCallError("EINVAL", call2);
11172
+ return session ? { session: true } : pgid !== void 0 ? { pgid } : {};
11173
+ }
11148
11174
  async function closeAll(io, fds) {
11149
11175
  for (const fd of fds) if (fd !== void 0) await io.close(fd).catch(() => void 0);
11150
11176
  }
@@ -12201,6 +12227,7 @@ function decodeRun(bytes, stdout, stderr) {
12201
12227
  function runSync(kernel, d, o) {
12202
12228
  const [file] = o.argv;
12203
12229
  if (file === void 0) throw new JsCallError("EINVAL", "run");
12230
+ const group = groupOf(o, "run");
12204
12231
  const stdout = stdioOf(o.stdout);
12205
12232
  const stderr = stderrOf(o.stderr);
12206
12233
  const input = typeof o.input === "string" ? encoder2.encode(o.input) : o.input;
@@ -12212,6 +12239,7 @@ function runSync(kernel, d, o) {
12212
12239
  argv: [...o.argv],
12213
12240
  env: { ...o.env ?? d.env },
12214
12241
  cwd: o.cwd === void 0 ? d.cwd : d.resolve(o.cwd),
12242
+ ...group,
12215
12243
  stdin: stdioOf(o.stdin),
12216
12244
  ...input ? { input } : {},
12217
12245
  stdout,
@@ -12227,6 +12255,7 @@ var encoder2, STDIO4;
12227
12255
  var init_js_run = __esm({
12228
12256
  "src/process/js/js-run.ts"() {
12229
12257
  "use strict";
12258
+ init_js_children();
12230
12259
  init_js_kernel();
12231
12260
  encoder2 = new TextEncoder();
12232
12261
  STDIO4 = /* @__PURE__ */ new Set(["pipe", "ignore", "inherit"]);