@ai-ecoverse/slicc-kernel 1.146.1 → 1.146.3

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.
@@ -1957,6 +1957,317 @@ var init_signals = __esm({
1957
1957
  }
1958
1958
  });
1959
1959
 
1960
+ // src/realm/sync-sab-bridge.ts
1961
+ function exactBody(req, transfer = []) {
1962
+ const body = req.body;
1963
+ if (!ArrayBuffer.isView(body)) return { req, transfer };
1964
+ if (Object.prototype.toString.call(body.buffer) === "[object SharedArrayBuffer]") {
1965
+ return { req, transfer };
1966
+ }
1967
+ const whole = body.constructor === Uint8Array && body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
1968
+ if (whole) return { req, transfer };
1969
+ const copy2 = new Uint8Array(body.byteLength);
1970
+ copy2.set(new Uint8Array(body.buffer, body.byteOffset, body.byteLength));
1971
+ return { req: { ...req, body: copy2 }, transfer: [...transfer, copy2.buffer] };
1972
+ }
1973
+ function syncCallCount() {
1974
+ return calls;
1975
+ }
1976
+ function lookedOutside() {
1977
+ looks++;
1978
+ }
1979
+ function syncEpoch() {
1980
+ return calls + looks;
1981
+ }
1982
+ function createSyncSabTransport(sab, port3, deps = {}) {
1983
+ const views = sabViews(sab);
1984
+ const { header, window } = views;
1985
+ const wait2 = deps.wait ?? ((a, i, v, t) => rawWait(a, i, v, t));
1986
+ const now = deps.now ?? (() => performance.now());
1987
+ let seq = 0;
1988
+ let typical = 0;
1989
+ const ready = (id) => Atomics.load(header, SAB_I_STATE) === SAB_STATE_READY && Atomics.load(header, SAB_I_SEQ) === id;
1990
+ function spinUntil(id, until) {
1991
+ for (let stride = 0; stride < SPIN_STRIDES; stride++) {
1992
+ for (let i = 0; i < SPIN_STRIDE; i++) if (ready(id)) return true;
1993
+ if (now() >= until) return false;
1994
+ }
1995
+ return false;
1996
+ }
1997
+ function settled2(start2) {
1998
+ typical += (Math.min(now() - start2, SPIN_CAP_MS) - typical) / 8;
1999
+ }
2000
+ function awaitReady(id, deadline, label) {
2001
+ const start2 = now();
2002
+ if (spinning && typical < SPIN_MS && spinUntil(id, start2 + SPIN_MS)) {
2003
+ settled2(start2);
2004
+ return;
2005
+ }
2006
+ for (; ; ) {
2007
+ const published = Atomics.load(header, SAB_I_PUB);
2008
+ if (ready(id)) {
2009
+ settled2(start2);
2010
+ return;
2011
+ }
2012
+ const remaining = deadline - now();
2013
+ if (remaining <= 0) throw syncError("EIO", label);
2014
+ wait2(header, SAB_I_PUB, published, remaining);
2015
+ }
2016
+ }
2017
+ return {
2018
+ call(asked, timeoutMs2, label, given = []) {
2019
+ if (deps.memory) publishMemory(sab, deps.memory());
2020
+ const { req, transfer } = exactBody(asked, given);
2021
+ const id = ++seq;
2022
+ calls += Number(!UNCOUNTED_OPS.has(req.op));
2023
+ let out = null;
2024
+ let status2 = 0;
2025
+ let offset = 0;
2026
+ Atomics.store(header, SAB_I_REQ, id);
2027
+ try {
2028
+ for (; ; ) {
2029
+ Atomics.store(header, SAB_I_STATE, SAB_STATE_PENDING);
2030
+ const msg = offset === 0 ? { type: SYNC_SAB_REQ_MSG, id, req } : { type: SYNC_SAB_NEXT_MSG, id, offset };
2031
+ try {
2032
+ if (offset === 0 && transfer.length > 0) port3.postMessage(msg, transfer);
2033
+ else port3.postMessage(msg);
2034
+ } catch {
2035
+ throw syncError("EIO", label);
2036
+ }
2037
+ awaitReady(id, now() + timeoutMs2, label);
2038
+ const total = loadU53(header, SAB_I_TOTAL, SAB_I_TOTAL_HI);
2039
+ const chunk = Atomics.load(header, SAB_I_CHUNK);
2040
+ const at = loadU53(header, SAB_I_OFFSET, SAB_I_OFFSET_HI);
2041
+ if (at !== offset || chunk < 0 || total < 0 || offset + chunk > total) {
2042
+ throw syncError("EIO", label);
2043
+ }
2044
+ if (out === null) {
2045
+ status2 = Atomics.load(header, SAB_I_STATUS);
2046
+ out = new Uint8Array(total);
2047
+ }
2048
+ out.set(window.subarray(0, chunk), offset);
2049
+ offset += chunk;
2050
+ if (offset >= total) break;
2051
+ if (chunk === 0) throw syncError("EIO", label);
2052
+ }
2053
+ } finally {
2054
+ Atomics.store(header, SAB_I_REQ, 0);
2055
+ Atomics.store(header, SAB_I_STATE, SAB_STATE_IDLE);
2056
+ }
2057
+ return decodeSabResult(status2, out);
2058
+ }
2059
+ };
2060
+ }
2061
+ function errnoError(code2, path, direct) {
2062
+ const err = syncError(code2, `sync-sab bridge, '${path}'`);
2063
+ return direct ? Object.assign(err, { direct }) : err;
2064
+ }
2065
+ function createSyncFsSabBridge(transport, opts = {}) {
2066
+ const direct = opts.direct ? { direct: true } : {};
2067
+ const timeoutMs2 = opts.timeoutMs ?? SYNC_FS_REQUEST_TIMEOUT_MS;
2068
+ let identity = {};
2069
+ let once = false;
2070
+ let last = null;
2071
+ function run(req, path, transfer) {
2072
+ last = null;
2073
+ const silence = SYNC_FS_READ_ONLY.has(req.op) ? timeoutMs2 : Number.POSITIVE_INFINITY;
2074
+ const result = transport.call(req, silence, `sync-sab bridge, '${path}'`, transfer);
2075
+ if (!result.ok) throw errnoError(result.errno, path, result.direct);
2076
+ return result;
2077
+ }
2078
+ function bytes(req, path) {
2079
+ const r = run(req, path);
2080
+ if (r.ok && r.kind === "bytes") return r.bytes;
2081
+ throw errnoError("EIO", path);
2082
+ }
2083
+ function json2(req, path) {
2084
+ const r = run(req, path);
2085
+ if (r.ok && r.kind === "json") return r.json;
2086
+ throw errnoError("EIO", path);
2087
+ }
2088
+ const changing = (req, path, transfer) => {
2089
+ const ask = once ? { identity: true } : identity;
2090
+ once = false;
2091
+ const r = run({ ...req, ...ask }, path, transfer);
2092
+ if (r.ok && r.kind === "json") last = parseSyncFsStat(r.json);
2093
+ };
2094
+ const io = (id) => ({
2095
+ readFile: (path) => bytes({ op: "read", path, ...id }, path),
2096
+ writeFile: (path, data, open) => {
2097
+ changing({ op: "write", path, body: data, ...open ? { mode: 1 } : {}, ...id }, path);
2098
+ },
2099
+ pread: (path, offset, length, version) => bytes({ op: "pread", path, offset, length, ...version ? { version } : {}, ...id }, path),
2100
+ pwrite: (path, offset, body, transfer) => {
2101
+ const whole = body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
2102
+ const owned = transfer && whole && body.buffer instanceof ArrayBuffer;
2103
+ const transferred = owned ? [body.buffer] : [];
2104
+ changing({ op: "pwrite", path, offset, body, ...id }, path, transferred);
2105
+ },
2106
+ truncate: (path, length) => {
2107
+ changing({ op: "truncate", path, length, ...id }, path);
2108
+ },
2109
+ append: (path, body) => json2({ op: "append", path, body, ...id }, path)
2110
+ });
2111
+ return {
2112
+ ...io({}),
2113
+ pinned: (handle) => io({ handle }),
2114
+ kept: (handle) => json2({ op: "kept", path: "/", handle }, "/") === true,
2115
+ keptStat: (handle) => {
2116
+ const s = parseSyncFsStat(json2({ op: "stat", path: "/", handle }, "/"));
2117
+ if (!s) throw errnoError("EIO", "/");
2118
+ return s;
2119
+ },
2120
+ stat: (path) => {
2121
+ const s = parseSyncFsStat(json2({ op: "stat", path, ...direct }, path));
2122
+ if (!s) throw errnoError("EIO", path);
2123
+ return s;
2124
+ },
2125
+ lstat: (path) => {
2126
+ const s = parseSyncFsStat(json2({ op: "lstat", path, ...direct }, path));
2127
+ if (!s) throw errnoError("EIO", path);
2128
+ return s;
2129
+ },
2130
+ readdir: (path) => {
2131
+ const list = json2({ op: "readdir", path }, path);
2132
+ if (!Array.isArray(list) || !list.every((s) => typeof s === "string")) {
2133
+ throw errnoError("EIO", path);
2134
+ }
2135
+ return list;
2136
+ },
2137
+ readdirStat: (path) => {
2138
+ const list = json2({ op: "readdir-stat", path }, path);
2139
+ if (!Array.isArray(list)) throw errnoError("EIO", path);
2140
+ return list.map((entry) => {
2141
+ if (!Array.isArray(entry) || typeof entry[0] !== "string") throw errnoError("EIO", path);
2142
+ if (entry[1] === null) return [entry[0], null];
2143
+ const stat = parseSyncFsStat(entry[1]);
2144
+ if (!stat) throw errnoError("EIO", path);
2145
+ return [entry[0], stat];
2146
+ });
2147
+ },
2148
+ exists: (path) => {
2149
+ const v = json2({ op: "exists", path }, path);
2150
+ if (typeof v !== "boolean") throw errnoError("EIO", path);
2151
+ return v;
2152
+ },
2153
+ mkdir: (path, mode) => {
2154
+ run({ op: "mkdir", path, exclusive: true, ...mode !== void 0 ? { mode } : {} }, path);
2155
+ },
2156
+ rm: (path) => {
2157
+ run({ op: "rm", path }, path);
2158
+ },
2159
+ rename: (from, to) => {
2160
+ const r = run({ op: "rename", path: from, arg2: to }, from);
2161
+ const seq = r.ok && r.kind === "json" ? r.json.seq : void 0;
2162
+ return typeof seq === "number" ? seq : void 0;
2163
+ },
2164
+ link: (from, to, follow3) => {
2165
+ run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
2166
+ },
2167
+ unlink: (path) => {
2168
+ run({ op: "unlink", path }, path);
2169
+ },
2170
+ rmdir: (path) => {
2171
+ run({ op: "rmdir", path }, path);
2172
+ },
2173
+ symlink: (target, linkPath) => {
2174
+ run({ op: "symlink", path: linkPath, arg2: target }, linkPath);
2175
+ },
2176
+ readlink: (path) => {
2177
+ const target = json2({ op: "readlink", path }, path);
2178
+ if (typeof target !== "string") throw errnoError("EIO", path);
2179
+ return target;
2180
+ },
2181
+ chmod: (path, mode) => {
2182
+ changing({ op: "chmod", path, mode }, path);
2183
+ },
2184
+ utimes: (path, atimeMs, mtimeMs, now) => {
2185
+ changing({ op: "utimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
2186
+ },
2187
+ identify: () => {
2188
+ identity = { identity: true };
2189
+ },
2190
+ identifyNext: () => {
2191
+ once = true;
2192
+ last = null;
2193
+ },
2194
+ identified: () => {
2195
+ once = false;
2196
+ return last;
2197
+ },
2198
+ lutimes: (path, atimeMs, mtimeMs, now) => {
2199
+ run({ op: "lutimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
2200
+ },
2201
+ mkfifo: (path, mode) => {
2202
+ run({ op: "mkfifo", path, mode }, path);
2203
+ },
2204
+ copy: (from, to, mode, exclusive) => {
2205
+ run({ op: "copy", path: from, arg2: to, mode, ...exclusive ? { exclusive } : {} }, to);
2206
+ },
2207
+ create: (path, mode, opening2) => {
2208
+ const flags = { ...mode !== void 0 ? { mode } : {}, ...opening2 ? { opening: opening2 } : {} };
2209
+ const r = run({ op: "create", path, ...flags, identity: true }, path);
2210
+ if (!r.ok || r.kind !== "json") return void 0;
2211
+ const st = parseSyncFsStat(r.json);
2212
+ if (!st) return void 0;
2213
+ const { seen } = r.json;
2214
+ return typeof seen === "number" ? { ...st, seen } : st;
2215
+ },
2216
+ chown: (path, uid, gid, follow3, handle) => {
2217
+ const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
2218
+ changing(
2219
+ {
2220
+ op: follow3 ? "chown" : "lchown",
2221
+ path,
2222
+ ...ids,
2223
+ ...handle !== void 0 ? { handle } : {}
2224
+ },
2225
+ path
2226
+ );
2227
+ },
2228
+ ...opts.owners ? { owners: true } : {},
2229
+ ...opts.links ? { links: true } : {},
2230
+ ...opts.changes ? { changes: new ChangeView(opts.changes) } : {},
2231
+ access: (path, mode, kind = "access", nofollow) => {
2232
+ run({ op: "access", path, mode, arg2: kind, ...nofollow ? { nofollow } : {} }, path);
2233
+ },
2234
+ hold: (path, held2, open, handle, want = 0, seen = {}) => {
2235
+ const mode = (held2 ? 1 : 0) | (open ? 2 : 0);
2236
+ if (mode === 3) {
2237
+ const at = seen.gen !== void 0 ? { gen: seen.gen } : {};
2238
+ const link = seen.nofollow ? { nofollow: true } : {};
2239
+ return json2({ op: "hold", path, mode: mode | want, ...at, ...link }, path);
2240
+ }
2241
+ run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
2242
+ return void 0;
2243
+ },
2244
+ statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path)),
2245
+ renames: (since, held2) => json2(
2246
+ { op: "renames", path: "/", offset: since, arg2: JSON.stringify(held2) },
2247
+ "/"
2248
+ )
2249
+ };
2250
+ }
2251
+ var UNCOUNTED_OPS, calls, looks, SPIN_MS, SPIN_STRIDE, SPIN_STRIDES, SPIN_CORES, spinning, SPIN_CAP_MS;
2252
+ var init_sync_sab_bridge = __esm({
2253
+ "src/realm/sync-sab-bridge.ts"() {
2254
+ "use strict";
2255
+ init_changes();
2256
+ init_cpu_clock();
2257
+ init_sync_fs_wire();
2258
+ init_sync_sab_wire();
2259
+ UNCOUNTED_OPS = /* @__PURE__ */ new Set([...SYNC_FS_OPS, "cwd-check", "cwd-chdir"]);
2260
+ calls = 0;
2261
+ looks = 0;
2262
+ SPIN_MS = 0.06;
2263
+ SPIN_STRIDE = 128;
2264
+ SPIN_STRIDES = 256;
2265
+ SPIN_CORES = 4;
2266
+ spinning = (globalThis.navigator?.hardwareConcurrency ?? 0) >= SPIN_CORES;
2267
+ SPIN_CAP_MS = 1;
2268
+ }
2269
+ });
2270
+
1960
2271
  // src/process/js/async-sab.ts
1961
2272
  async function changed(header, index3, seen, waitAsync = defaultWaitAsync) {
1962
2273
  const waited = waitAsync(header, index3, seen);
@@ -1975,7 +2286,8 @@ function createAsyncSabTransport(sab, port3, waitAsync = defaultWaitAsync) {
1975
2286
  await changed(header, SAB_I_PUB, published, waitAsync);
1976
2287
  }
1977
2288
  }
1978
- async function once(req) {
2289
+ async function once(asked) {
2290
+ const { req, transfer } = exactBody(asked);
1979
2291
  const id = ++seq;
1980
2292
  let out = null;
1981
2293
  let status2 = 0;
@@ -1984,9 +2296,8 @@ function createAsyncSabTransport(sab, port3, waitAsync = defaultWaitAsync) {
1984
2296
  try {
1985
2297
  for (; ; ) {
1986
2298
  Atomics.store(header, SAB_I_STATE, SAB_STATE_PENDING);
1987
- port3.postMessage(
1988
- offset === 0 ? { type: SYNC_SAB_REQ_MSG, id, req } : { type: SYNC_SAB_NEXT_MSG, id, offset }
1989
- );
2299
+ if (offset === 0) port3.postMessage({ type: SYNC_SAB_REQ_MSG, id, req }, transfer);
2300
+ else port3.postMessage({ type: SYNC_SAB_NEXT_MSG, id, offset });
1990
2301
  await ready(id);
1991
2302
  const total = loadU53(header, SAB_I_TOTAL, SAB_I_TOTAL_HI);
1992
2303
  const chunk = Atomics.load(header, SAB_I_CHUNK);
@@ -2021,6 +2332,7 @@ var defaultWaitAsync;
2021
2332
  var init_async_sab = __esm({
2022
2333
  "src/process/js/async-sab.ts"() {
2023
2334
  "use strict";
2335
+ init_sync_sab_bridge();
2024
2336
  init_sync_sab_wire();
2025
2337
  defaultWaitAsync = (a, i, v) => Atomics.waitAsync(a, i, v);
2026
2338
  }
@@ -3747,10 +4059,9 @@ var init_wasi_fds = __esm({
3747
4059
  if (exclusive && !(oflags & OFLAGS.DIRECTORY) && this.madeAtOnce(path, mode)) {
3748
4060
  return this.regular(path, void 0, oflags, rights, fdflags, mode, true);
3749
4061
  }
3750
- if ((exclusive || nofollow) && this.isLink(path)) {
3751
- throw new WasiError(exclusive ? "EEXIST" : "ELOOP");
3752
- }
3753
- const s = this.statOrMissing(path);
4062
+ if (exclusive && !nofollow && this.isLink(path)) throw new WasiError("EEXIST");
4063
+ const s = nofollow ? this.lstatOrMissing(path) : this.statOrMissing(path);
4064
+ if (s?.isSymbolicLink) throw new WasiError(exclusive ? "EEXIST" : "ELOOP");
3754
4065
  if (exclusive && s) throw new WasiError("EEXIST");
3755
4066
  if (s?.escape !== void 0) {
3756
4067
  refuseWrite({ readonly: true }, oflags, rights);
@@ -3769,6 +4080,11 @@ var init_wasi_fds = __esm({
3769
4080
  return this.regular(path, s, oflags, rights, fdflags, mode);
3770
4081
  }
3771
4082
  nofollow = false;
4083
+ inos = /* @__PURE__ */ new WeakMap();
4084
+ otherFile(buffer, st) {
4085
+ const ino = this.inos.get(buffer);
4086
+ return ino !== void 0 && st?.ino !== void 0 && ino !== st.ino;
4087
+ }
3772
4088
  openSpecial(path, oflags, rights, fdflags, exclusive) {
3773
4089
  if (exclusive && namedDevice(path)) throw new WasiError("EEXIST");
3774
4090
  const device2 = deviceOf(path);
@@ -3826,6 +4142,7 @@ var init_wasi_fds = __esm({
3826
4142
  buffer = void 0;
3827
4143
  }
3828
4144
  buffer ??= this.sharing(path, existing);
4145
+ if (buffer && this.nofollow && this.otherFile(buffer, existing)) buffer = void 0;
3829
4146
  const want = wantOf(oflags, rights);
3830
4147
  if (buffer) {
3831
4148
  if (this.fs.owners) this.fs.access?.(path, want, "open");
@@ -3870,6 +4187,7 @@ var init_wasi_fds = __esm({
3870
4187
  const buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version, watch);
3871
4188
  buffer.moved = (missing2) => this.followRenames(missing2);
3872
4189
  buffer.handle = handle;
4190
+ if (st.ino !== void 0) this.inos.set(buffer, st.ino);
3873
4191
  this.buffers.set(path, buffer);
3874
4192
  const id = this.identity(st);
3875
4193
  if (id !== void 0) this.know(buffer, id);
@@ -3952,6 +4270,14 @@ var init_wasi_fds = __esm({
3952
4270
  return false;
3953
4271
  }
3954
4272
  }
4273
+ lstatOrMissing(path) {
4274
+ try {
4275
+ return this.fs.lstat(path);
4276
+ } catch (e) {
4277
+ if (e.code === "ENOENT") return void 0;
4278
+ throw e;
4279
+ }
4280
+ }
3955
4281
  statOrMissing(path) {
3956
4282
  try {
3957
4283
  return this.fs.stat(path);
@@ -6800,7 +7126,7 @@ var KERNEL_VERSION, OS_RELEASE;
6800
7126
  var init_version = __esm({
6801
7127
  "src/version.ts"() {
6802
7128
  "use strict";
6803
- KERNEL_VERSION = true ? "1.146.1" : "0.0.0-dev";
7129
+ KERNEL_VERSION = true ? "1.146.3" : "0.0.0-dev";
6804
7130
  OS_RELEASE = "6.0.0-slicc";
6805
7131
  }
6806
7132
  });
@@ -7912,367 +8238,69 @@ function mayTrace(viewer, target) {
7912
8238
  }
7913
8239
  function fileIdentity(ino, mtimeMs) {
7914
8240
  if (ino === void 0 || mtimeMs === void 0 || !Number.isFinite(mtimeMs)) return void 0;
7915
- return `${ino}:${Math.trunc(mtimeMs)}`;
7916
- }
7917
- var init_proc_info = __esm({
7918
- "src/kernel/proc-info.ts"() {
7919
- "use strict";
7920
- }
7921
- });
7922
-
7923
- // src/fs/owners.ts
7924
- function inGroup(cred, gid) {
7925
- return cred.egid === gid || cred.groups.includes(gid);
7926
- }
7927
- var ROOT_OWNER;
7928
- var init_owners = __esm({
7929
- "src/fs/owners.ts"() {
7930
- "use strict";
7931
- init_types();
7932
- ROOT_OWNER = Object.freeze({ uid: 0, gid: 0 });
7933
- }
7934
- });
7935
-
7936
- // src/fs/walk.ts
7937
- var init_walk = __esm({
7938
- "src/fs/walk.ts"() {
7939
- "use strict";
7940
- init_types();
7941
- }
7942
- });
7943
-
7944
- // src/fs/access.ts
7945
- function permits(cred, perm, want, directory = true) {
7946
- const mode = perm.mode ?? (directory ? 493 : 420);
7947
- if (cred.euid === 0) return (want & X_OK) === 0 || directory || (mode & 73) !== 0;
7948
- const shift = cred.euid === perm.uid ? 6 : inGroup(cred, perm.gid) ? 3 : 0;
7949
- return (mode >> shift & want) === want;
7950
- }
7951
- var X_OK;
7952
- var init_access = __esm({
7953
- "src/fs/access.ts"() {
7954
- "use strict";
7955
- init_owners();
7956
- init_types();
7957
- init_walk();
7958
- X_OK = 1;
7959
- }
7960
- });
7961
-
7962
- // src/process/wasi-errno.ts
7963
- function wasiErrno(code2) {
7964
- return WASI_ERRNO[code2] ?? E.IO;
7965
- }
7966
- var WASI_ERRNO;
7967
- var init_wasi_errno = __esm({
7968
- "src/process/wasi-errno.ts"() {
7969
- "use strict";
7970
- init_wasi_abi();
7971
- WASI_ERRNO = {
7972
- ...Object.fromEntries(Object.entries(E).map(([name2, errno2]) => [`E${name2}`, errno2])),
7973
- EWOULDBLOCK: E.AGAIN,
7974
- ENOTSUP: 138,
7975
- EOPNOTSUPP: 138,
7976
- ENOMEDIUM: 148
7977
- };
7978
- }
7979
- });
7980
-
7981
- // src/realm/sync-sab-bridge.ts
7982
- function syncCallCount() {
7983
- return calls;
7984
- }
7985
- function lookedOutside() {
7986
- looks++;
7987
- }
7988
- function syncEpoch() {
7989
- return calls + looks;
7990
- }
7991
- function createSyncSabTransport(sab, port3, deps = {}) {
7992
- const views = sabViews(sab);
7993
- const { header, window } = views;
7994
- const wait2 = deps.wait ?? ((a, i, v, t) => rawWait(a, i, v, t));
7995
- const now = deps.now ?? (() => performance.now());
7996
- let seq = 0;
7997
- let typical = 0;
7998
- const ready = (id) => Atomics.load(header, SAB_I_STATE) === SAB_STATE_READY && Atomics.load(header, SAB_I_SEQ) === id;
7999
- function spinUntil(id, until) {
8000
- for (let stride = 0; stride < SPIN_STRIDES; stride++) {
8001
- for (let i = 0; i < SPIN_STRIDE; i++) if (ready(id)) return true;
8002
- if (now() >= until) return false;
8003
- }
8004
- return false;
8005
- }
8006
- function settled2(start2) {
8007
- typical += (Math.min(now() - start2, SPIN_CAP_MS) - typical) / 8;
8008
- }
8009
- function awaitReady(id, deadline, label) {
8010
- const start2 = now();
8011
- if (spinning && typical < SPIN_MS && spinUntil(id, start2 + SPIN_MS)) {
8012
- settled2(start2);
8013
- return;
8014
- }
8015
- for (; ; ) {
8016
- const published = Atomics.load(header, SAB_I_PUB);
8017
- if (ready(id)) {
8018
- settled2(start2);
8019
- return;
8020
- }
8021
- const remaining = deadline - now();
8022
- if (remaining <= 0) throw syncError("EIO", label);
8023
- wait2(header, SAB_I_PUB, published, remaining);
8024
- }
8025
- }
8026
- return {
8027
- call(req, timeoutMs2, label, transfer = []) {
8028
- if (deps.memory) publishMemory(sab, deps.memory());
8029
- const id = ++seq;
8030
- calls += Number(!UNCOUNTED_OPS.has(req.op));
8031
- let out = null;
8032
- let status2 = 0;
8033
- let offset = 0;
8034
- Atomics.store(header, SAB_I_REQ, id);
8035
- try {
8036
- for (; ; ) {
8037
- Atomics.store(header, SAB_I_STATE, SAB_STATE_PENDING);
8038
- const msg = offset === 0 ? { type: SYNC_SAB_REQ_MSG, id, req } : { type: SYNC_SAB_NEXT_MSG, id, offset };
8039
- try {
8040
- if (offset === 0 && transfer.length > 0) port3.postMessage(msg, transfer);
8041
- else port3.postMessage(msg);
8042
- } catch {
8043
- throw syncError("EIO", label);
8044
- }
8045
- awaitReady(id, now() + timeoutMs2, label);
8046
- const total = loadU53(header, SAB_I_TOTAL, SAB_I_TOTAL_HI);
8047
- const chunk = Atomics.load(header, SAB_I_CHUNK);
8048
- const at = loadU53(header, SAB_I_OFFSET, SAB_I_OFFSET_HI);
8049
- if (at !== offset || chunk < 0 || total < 0 || offset + chunk > total) {
8050
- throw syncError("EIO", label);
8051
- }
8052
- if (out === null) {
8053
- status2 = Atomics.load(header, SAB_I_STATUS);
8054
- out = new Uint8Array(total);
8055
- }
8056
- out.set(window.subarray(0, chunk), offset);
8057
- offset += chunk;
8058
- if (offset >= total) break;
8059
- if (chunk === 0) throw syncError("EIO", label);
8060
- }
8061
- } finally {
8062
- Atomics.store(header, SAB_I_REQ, 0);
8063
- Atomics.store(header, SAB_I_STATE, SAB_STATE_IDLE);
8064
- }
8065
- return decodeSabResult(status2, out);
8066
- }
8067
- };
8068
- }
8069
- function errnoError(code2, path, direct) {
8070
- const err = syncError(code2, `sync-sab bridge, '${path}'`);
8071
- return direct ? Object.assign(err, { direct }) : err;
8241
+ return `${ino}:${Math.trunc(mtimeMs)}`;
8072
8242
  }
8073
- function createSyncFsSabBridge(transport, opts = {}) {
8074
- const direct = opts.direct ? { direct: true } : {};
8075
- const timeoutMs2 = opts.timeoutMs ?? SYNC_FS_REQUEST_TIMEOUT_MS;
8076
- let identity = {};
8077
- let once = false;
8078
- let last = null;
8079
- function run(req, path, transfer) {
8080
- last = null;
8081
- const silence = SYNC_FS_READ_ONLY.has(req.op) ? timeoutMs2 : Number.POSITIVE_INFINITY;
8082
- const result = transport.call(req, silence, `sync-sab bridge, '${path}'`, transfer);
8083
- if (!result.ok) throw errnoError(result.errno, path, result.direct);
8084
- return result;
8243
+ var init_proc_info = __esm({
8244
+ "src/kernel/proc-info.ts"() {
8245
+ "use strict";
8085
8246
  }
8086
- function bytes(req, path) {
8087
- const r = run(req, path);
8088
- if (r.ok && r.kind === "bytes") return r.bytes;
8089
- throw errnoError("EIO", path);
8247
+ });
8248
+
8249
+ // src/fs/owners.ts
8250
+ function inGroup(cred, gid) {
8251
+ return cred.egid === gid || cred.groups.includes(gid);
8252
+ }
8253
+ var ROOT_OWNER;
8254
+ var init_owners = __esm({
8255
+ "src/fs/owners.ts"() {
8256
+ "use strict";
8257
+ init_types();
8258
+ ROOT_OWNER = Object.freeze({ uid: 0, gid: 0 });
8090
8259
  }
8091
- function json2(req, path) {
8092
- const r = run(req, path);
8093
- if (r.ok && r.kind === "json") return r.json;
8094
- throw errnoError("EIO", path);
8260
+ });
8261
+
8262
+ // src/fs/walk.ts
8263
+ var init_walk = __esm({
8264
+ "src/fs/walk.ts"() {
8265
+ "use strict";
8266
+ init_types();
8095
8267
  }
8096
- const changing = (req, path, transfer) => {
8097
- const ask = once ? { identity: true } : identity;
8098
- once = false;
8099
- const r = run({ ...req, ...ask }, path, transfer);
8100
- if (r.ok && r.kind === "json") last = parseSyncFsStat(r.json);
8101
- };
8102
- const io = (id) => ({
8103
- readFile: (path) => bytes({ op: "read", path, ...id }, path),
8104
- writeFile: (path, data, open) => {
8105
- changing({ op: "write", path, body: data, ...open ? { mode: 1 } : {}, ...id }, path);
8106
- },
8107
- pread: (path, offset, length, version) => bytes({ op: "pread", path, offset, length, ...version ? { version } : {}, ...id }, path),
8108
- pwrite: (path, offset, body, transfer) => {
8109
- const whole = body.byteOffset === 0 && body.byteLength === body.buffer.byteLength;
8110
- const owned = transfer && whole && body.buffer instanceof ArrayBuffer;
8111
- const transferred = owned ? [body.buffer] : [];
8112
- changing({ op: "pwrite", path, offset, body, ...id }, path, transferred);
8113
- },
8114
- truncate: (path, length) => {
8115
- changing({ op: "truncate", path, length, ...id }, path);
8116
- },
8117
- append: (path, body) => json2({ op: "append", path, body, ...id }, path)
8118
- });
8119
- return {
8120
- ...io({}),
8121
- pinned: (handle) => io({ handle }),
8122
- kept: (handle) => json2({ op: "kept", path: "/", handle }, "/") === true,
8123
- keptStat: (handle) => {
8124
- const s = parseSyncFsStat(json2({ op: "stat", path: "/", handle }, "/"));
8125
- if (!s) throw errnoError("EIO", "/");
8126
- return s;
8127
- },
8128
- stat: (path) => {
8129
- const s = parseSyncFsStat(json2({ op: "stat", path, ...direct }, path));
8130
- if (!s) throw errnoError("EIO", path);
8131
- return s;
8132
- },
8133
- lstat: (path) => {
8134
- const s = parseSyncFsStat(json2({ op: "lstat", path, ...direct }, path));
8135
- if (!s) throw errnoError("EIO", path);
8136
- return s;
8137
- },
8138
- readdir: (path) => {
8139
- const list = json2({ op: "readdir", path }, path);
8140
- if (!Array.isArray(list) || !list.every((s) => typeof s === "string")) {
8141
- throw errnoError("EIO", path);
8142
- }
8143
- return list;
8144
- },
8145
- readdirStat: (path) => {
8146
- const list = json2({ op: "readdir-stat", path }, path);
8147
- if (!Array.isArray(list)) throw errnoError("EIO", path);
8148
- return list.map((entry) => {
8149
- if (!Array.isArray(entry) || typeof entry[0] !== "string") throw errnoError("EIO", path);
8150
- if (entry[1] === null) return [entry[0], null];
8151
- const stat = parseSyncFsStat(entry[1]);
8152
- if (!stat) throw errnoError("EIO", path);
8153
- return [entry[0], stat];
8154
- });
8155
- },
8156
- exists: (path) => {
8157
- const v = json2({ op: "exists", path }, path);
8158
- if (typeof v !== "boolean") throw errnoError("EIO", path);
8159
- return v;
8160
- },
8161
- mkdir: (path, mode) => {
8162
- run({ op: "mkdir", path, exclusive: true, ...mode !== void 0 ? { mode } : {} }, path);
8163
- },
8164
- rm: (path) => {
8165
- run({ op: "rm", path }, path);
8166
- },
8167
- rename: (from, to) => {
8168
- const r = run({ op: "rename", path: from, arg2: to }, from);
8169
- const seq = r.ok && r.kind === "json" ? r.json.seq : void 0;
8170
- return typeof seq === "number" ? seq : void 0;
8171
- },
8172
- link: (from, to, follow3) => {
8173
- run({ op: "link", path: from, arg2: to, ...follow3 ? { mode: 1 } : {} }, from);
8174
- },
8175
- unlink: (path) => {
8176
- run({ op: "unlink", path }, path);
8177
- },
8178
- rmdir: (path) => {
8179
- run({ op: "rmdir", path }, path);
8180
- },
8181
- symlink: (target, linkPath) => {
8182
- run({ op: "symlink", path: linkPath, arg2: target }, linkPath);
8183
- },
8184
- readlink: (path) => {
8185
- const target = json2({ op: "readlink", path }, path);
8186
- if (typeof target !== "string") throw errnoError("EIO", path);
8187
- return target;
8188
- },
8189
- chmod: (path, mode) => {
8190
- changing({ op: "chmod", path, mode }, path);
8191
- },
8192
- utimes: (path, atimeMs, mtimeMs, now) => {
8193
- changing({ op: "utimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
8194
- },
8195
- identify: () => {
8196
- identity = { identity: true };
8197
- },
8198
- identifyNext: () => {
8199
- once = true;
8200
- last = null;
8201
- },
8202
- identified: () => {
8203
- once = false;
8204
- return last;
8205
- },
8206
- lutimes: (path, atimeMs, mtimeMs, now) => {
8207
- run({ op: "lutimes", path, atimeMs, mtimeMs, ...now ? { now } : {} }, path);
8208
- },
8209
- mkfifo: (path, mode) => {
8210
- run({ op: "mkfifo", path, mode }, path);
8211
- },
8212
- copy: (from, to, mode, exclusive) => {
8213
- run({ op: "copy", path: from, arg2: to, mode, ...exclusive ? { exclusive } : {} }, to);
8214
- },
8215
- create: (path, mode, opening2) => {
8216
- const flags = { ...mode !== void 0 ? { mode } : {}, ...opening2 ? { opening: opening2 } : {} };
8217
- const r = run({ op: "create", path, ...flags, identity: true }, path);
8218
- if (!r.ok || r.kind !== "json") return void 0;
8219
- const st = parseSyncFsStat(r.json);
8220
- if (!st) return void 0;
8221
- const { seen } = r.json;
8222
- return typeof seen === "number" ? { ...st, seen } : st;
8223
- },
8224
- chown: (path, uid, gid, follow3, handle) => {
8225
- const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
8226
- changing(
8227
- {
8228
- op: follow3 ? "chown" : "lchown",
8229
- path,
8230
- ...ids,
8231
- ...handle !== void 0 ? { handle } : {}
8232
- },
8233
- path
8234
- );
8235
- },
8236
- ...opts.owners ? { owners: true } : {},
8237
- ...opts.links ? { links: true } : {},
8238
- ...opts.changes ? { changes: new ChangeView(opts.changes) } : {},
8239
- access: (path, mode, kind = "access", nofollow) => {
8240
- run({ op: "access", path, mode, arg2: kind, ...nofollow ? { nofollow } : {} }, path);
8241
- },
8242
- hold: (path, held2, open, handle, want = 0, seen = {}) => {
8243
- const mode = (held2 ? 1 : 0) | (open ? 2 : 0);
8244
- if (mode === 3) {
8245
- const at = seen.gen !== void 0 ? { gen: seen.gen } : {};
8246
- const link = seen.nofollow ? { nofollow: true } : {};
8247
- return json2({ op: "hold", path, mode: mode | want, ...at, ...link }, path);
8248
- }
8249
- run({ op: "hold", path, mode, ...handle !== void 0 ? { handle } : {} }, path);
8250
- return void 0;
8251
- },
8252
- statfs: (path = "/") => parseSyncFsUsage(json2({ op: "statfs", path }, path)),
8253
- renames: (since, held2) => json2(
8254
- { op: "renames", path: "/", offset: since, arg2: JSON.stringify(held2) },
8255
- "/"
8256
- )
8257
- };
8268
+ });
8269
+
8270
+ // src/fs/access.ts
8271
+ function permits(cred, perm, want, directory = true) {
8272
+ const mode = perm.mode ?? (directory ? 493 : 420);
8273
+ if (cred.euid === 0) return (want & X_OK) === 0 || directory || (mode & 73) !== 0;
8274
+ const shift = cred.euid === perm.uid ? 6 : inGroup(cred, perm.gid) ? 3 : 0;
8275
+ return (mode >> shift & want) === want;
8258
8276
  }
8259
- var UNCOUNTED_OPS, calls, looks, SPIN_MS, SPIN_STRIDE, SPIN_STRIDES, SPIN_CORES, spinning, SPIN_CAP_MS;
8260
- var init_sync_sab_bridge = __esm({
8261
- "src/realm/sync-sab-bridge.ts"() {
8277
+ var X_OK;
8278
+ var init_access = __esm({
8279
+ "src/fs/access.ts"() {
8262
8280
  "use strict";
8263
- init_changes();
8264
- init_cpu_clock();
8265
- init_sync_fs_wire();
8266
- init_sync_sab_wire();
8267
- UNCOUNTED_OPS = /* @__PURE__ */ new Set([...SYNC_FS_OPS, "cwd-check", "cwd-chdir"]);
8268
- calls = 0;
8269
- looks = 0;
8270
- SPIN_MS = 0.06;
8271
- SPIN_STRIDE = 128;
8272
- SPIN_STRIDES = 256;
8273
- SPIN_CORES = 4;
8274
- spinning = (globalThis.navigator?.hardwareConcurrency ?? 0) >= SPIN_CORES;
8275
- SPIN_CAP_MS = 1;
8281
+ init_owners();
8282
+ init_types();
8283
+ init_walk();
8284
+ X_OK = 1;
8285
+ }
8286
+ });
8287
+
8288
+ // src/process/wasi-errno.ts
8289
+ function wasiErrno(code2) {
8290
+ return WASI_ERRNO[code2] ?? E.IO;
8291
+ }
8292
+ var WASI_ERRNO;
8293
+ var init_wasi_errno = __esm({
8294
+ "src/process/wasi-errno.ts"() {
8295
+ "use strict";
8296
+ init_wasi_abi();
8297
+ WASI_ERRNO = {
8298
+ ...Object.fromEntries(Object.entries(E).map(([name2, errno2]) => [`E${name2}`, errno2])),
8299
+ EWOULDBLOCK: E.AGAIN,
8300
+ ENOTSUP: 138,
8301
+ EOPNOTSUPP: 138,
8302
+ ENOMEDIUM: 148
8303
+ };
8276
8304
  }
8277
8305
  });
8278
8306
 
@@ -13969,9 +13997,12 @@ function ownBytes(bytes) {
13969
13997
  if (bytes.constructor === Uint8Array) return bytes;
13970
13998
  return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength).slice();
13971
13999
  }
14000
+ function ownedBuffer(body, given) {
14001
+ return body === given ? void 0 : [body.buffer];
14002
+ }
13972
14003
  function kernelSys(transport) {
13973
- const call2 = (req, label) => {
13974
- const r = transport.call(req, Number.POSITIVE_INFINITY, label);
14004
+ const call2 = (req, label, transfer) => {
14005
+ const r = transport.call(req, Number.POSITIVE_INFINITY, label, transfer);
13975
14006
  if (!r.ok) throw new SyscallError(r.errno);
13976
14007
  return r;
13977
14008
  };
@@ -13986,13 +14017,14 @@ function kernelSys(transport) {
13986
14017
  return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
13987
14018
  },
13988
14019
  write(fd, bytes, opts) {
14020
+ const body = ownBytes(bytes);
13989
14021
  const req = {
13990
14022
  op: "fd-write",
13991
14023
  fd,
13992
- body: ownBytes(bytes),
14024
+ body,
13993
14025
  ...opts?.nonblock ? { nonblock: true } : {}
13994
14026
  };
13995
- const n = json2(call2(req, `fd-write ${fd}`));
14027
+ const n = json2(call2(req, `fd-write ${fd}`, ownedBuffer(body, bytes)));
13996
14028
  return typeof n === "number" ? n : bytes.length;
13997
14029
  },
13998
14030
  close(fd) {
@@ -14037,8 +14069,9 @@ function kernelSys(transport) {
14037
14069
  return r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
14038
14070
  },
14039
14071
  pwrite(fd, bytes, at) {
14072
+ const body = ownBytes(bytes);
14040
14073
  return json2(
14041
- call2({ op: "fd-pwrite", fd, offset: at, body: ownBytes(bytes) }, `fd-pwrite ${fd}`)
14074
+ call2({ op: "fd-pwrite", fd, offset: at, body }, `fd-pwrite ${fd}`, ownedBuffer(body, bytes))
14042
14075
  );
14043
14076
  },
14044
14077
  isatty(fd) {