@ai-ecoverse/slicc-kernel 1.58.0 → 1.59.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.
@@ -567,6 +567,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
567
567
  };
568
568
  const invalidate = () => cache.mutated([]);
569
569
  const touched = (path, ino) => cache.changed(path, ino);
570
+ const { chown } = bridge;
570
571
  const mutating = (op, ...paths) => {
571
572
  try {
572
573
  return op();
@@ -622,11 +623,15 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
622
623
  ...bridge.kept ? { kept: bridge.kept.bind(bridge) } : {},
623
624
  ...bridge.pinned ? { pinned: (handle) => pinnedIo(bridge, handle, rewriting) } : {},
624
625
  ...bridge.create ? { create: (p) => mutating(() => bridge.create?.(p), ...entry(p)) } : {},
626
+ ...chown ? {
627
+ chown: (p, uid, gid, follow2) => rewriting(p, () => chown.call(bridge, p, uid, gid, follow2))
628
+ } : {},
625
629
  ...bridge.pread && bridge.pwrite && bridge.truncate ? {
626
630
  pread: bridge.pread.bind(bridge),
627
631
  pwrite: (p, at, bytes, transfer) => rewriting(p, () => bridge.pwrite?.(p, at, bytes, transfer)),
628
632
  truncate: (p, size) => rewriting(p, () => bridge.truncate?.(p, size))
629
633
  } : {},
634
+ ...bridge.owners ? { owners: true } : {},
630
635
  invalidate,
631
636
  touched
632
637
  };
@@ -2056,6 +2061,9 @@ var init_wasi_termios = __esm({
2056
2061
  });
2057
2062
 
2058
2063
  // src/process/wasi/wasi-host.ts
2064
+ function idOf(value2) {
2065
+ return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
2066
+ }
2059
2067
  function linkedOf(st) {
2060
2068
  return (st.nlink ?? 1) > 1 ? st : void 0;
2061
2069
  }
@@ -2124,7 +2132,7 @@ function wrap(table) {
2124
2132
  }
2125
2133
  return out;
2126
2134
  }
2127
- var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
2135
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
2128
2136
  var init_wasi_host = __esm({
2129
2137
  "src/process/wasi/wasi-host.ts"() {
2130
2138
  "use strict";
@@ -2146,6 +2154,8 @@ var init_wasi_host = __esm({
2146
2154
  IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
2147
2155
  NS_PER_MS = 1000000n;
2148
2156
  AT_SYMLINK_NOFOLLOW = 1;
2157
+ ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
2158
+ GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
2149
2159
  S_IFIFO = 4096;
2150
2160
  DEFAULT_UMASK = 18;
2151
2161
  MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
@@ -2217,7 +2227,60 @@ var init_wasi_host = __esm({
2217
2227
  return path;
2218
2228
  };
2219
2229
  const modeOf = (st) => (st.mode ?? 0) & 4095;
2230
+ const chown = (path, uid, gid, follow2) => {
2231
+ const { chown: own } = this.o.fs;
2232
+ if (!own) throw new WasiError("ENOSYS");
2233
+ own.call(this.o.fs, path, idOf(uid), idOf(gid), follow2);
2234
+ };
2235
+ const caller = () => {
2236
+ const cred = this.o.kernel.call({ op: "proc-cred" });
2237
+ return [cred.euid, cred.egid];
2238
+ };
2239
+ const owner = (st, out) => {
2240
+ const [uid, gid] = st?.uid === void 0 ? caller() : [st.uid, st.gid];
2241
+ const view = mem.view();
2242
+ view.getUint32(out + 4, true);
2243
+ view.setUint32(out, uid, true);
2244
+ view.setUint32(out + 4, gid, true);
2245
+ };
2246
+ const fdOwned = (fd) => {
2247
+ const e = fds.get(fd);
2248
+ if (e.type === "device") return ROOT_IDS;
2249
+ if (e.type === "kernel" && fds.kind(fd, e) !== "file") return void 0;
2250
+ try {
2251
+ return this.o.fs.stat(pathOf(fd));
2252
+ } catch (err) {
2253
+ if (!GONE.has(err?.code)) throw err;
2254
+ return void 0;
2255
+ }
2256
+ };
2257
+ const pathOwned = (path, follow2) => {
2258
+ if (deviceOf(path)) return ROOT_IDS;
2259
+ return follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
2260
+ };
2220
2261
  return wrap({
2262
+ fd_chown: (fd, uid, gid) => void chown(pathOf(fd), uid, gid, true),
2263
+ path_chown: (dirfd, p, l, uid, gid, flags) => void chown(at(dirfd, p, l), uid, gid, (flags & AT_SYMLINK_NOFOLLOW) === 0),
2264
+ fd_owner: (fd, out) => {
2265
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2266
+ owner(fdOwned(fd), out);
2267
+ },
2268
+ fd_filestat_owner: (fd, statOut, out) => {
2269
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2270
+ this.writeFilestat(statOut, this.fdFilestat(fd));
2271
+ owner(fdOwned(fd), out);
2272
+ },
2273
+ path_filestat_owner: (dirfd, lookup, p, l, statOut, out) => {
2274
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2275
+ const path = at(dirfd, p, l);
2276
+ this.writeFilestat(statOut, this.pathFilestat(path, lookup));
2277
+ owner(pathOwned(path, (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
2278
+ },
2279
+ path_owner: (dirfd, p, l, flags, out) => {
2280
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2281
+ const path = at(dirfd, p, l);
2282
+ owner(pathOwned(path, (flags & AT_SYMLINK_NOFOLLOW) === 0), out);
2283
+ },
2221
2284
  fd_chmod: (fd, mode) => void this.o.fs.chmod(pathOf(fd), mode & 4095),
2222
2285
  path_chmod: (dirfd, p, l, mode, flags) => void this.o.fs.chmod(target(at(dirfd, p, l), flags), mode & 4095),
2223
2286
  umask: (mask, out) => {
@@ -4511,9 +4574,9 @@ function createSyncFsSabBridge(transport, opts = {}) {
4511
4574
  create: (path, mode) => {
4512
4575
  run({ op: "create", path, ...mode !== void 0 ? { mode } : {} }, path);
4513
4576
  },
4514
- chown: (path, uid, gid) => {
4577
+ chown: (path, uid, gid, follow2) => {
4515
4578
  const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
4516
- run({ op: "lchown", path, ...ids }, path);
4579
+ run({ op: follow2 ? "chown" : "lchown", path, ...ids }, path);
4517
4580
  },
4518
4581
  ...opts.owners ? { owners: true } : {},
4519
4582
  hold: (path, held, open, handle) => {
@@ -5540,7 +5603,7 @@ function toMs(v) {
5540
5603
  function linkedStates(bridgeOf) {
5541
5604
  const opens = /* @__PURE__ */ new Map();
5542
5605
  const byId = /* @__PURE__ */ new Map();
5543
- const idOf2 = (st) => st?.ino === void 0 || (st.nlink ?? 1) < 2 ? void 0 : `${st.dev}:${st.ino}`;
5606
+ const idOf3 = (st) => st?.ino === void 0 || (st.nlink ?? 1) < 2 ? void 0 : `${st.dev}:${st.ino}`;
5544
5607
  function know(s, id) {
5545
5608
  s.id = id;
5546
5609
  if (!byId.has(id)) byId.set(id, s);
@@ -5554,14 +5617,14 @@ function linkedStates(bridgeOf) {
5554
5617
  return;
5555
5618
  }
5556
5619
  opens.set(s, node);
5557
- const id = idOf2(s.stat);
5620
+ const id = idOf3(s.stat);
5558
5621
  if (id !== void 0) know(s, id);
5559
5622
  }
5560
5623
  function sharedWith(node) {
5561
5624
  const st = node.live.stat;
5562
5625
  if (st?.ino === void 0) return void 0;
5563
5626
  const id = `${st.dev}:${st.ino}`;
5564
- if (!byId.has(id) && idOf2(st) !== void 0) {
5627
+ if (!byId.has(id) && idOf3(st) !== void 0) {
5565
5628
  for (const [s2, other] of opens) {
5566
5629
  if (s2.id !== void 0 || s2.orphan) continue;
5567
5630
  let st2;
@@ -5569,7 +5632,7 @@ function linkedStates(bridgeOf) {
5569
5632
  st2 = bridgeOf(other).lstat(liveNodePath(other));
5570
5633
  } catch {
5571
5634
  }
5572
- const known = idOf2(st2);
5635
+ const known = idOf3(st2);
5573
5636
  if (known !== void 0) know(s2, known);
5574
5637
  }
5575
5638
  }
@@ -5577,7 +5640,7 @@ function linkedStates(bridgeOf) {
5577
5640
  return s && s !== node.live && !stale(s) ? s : void 0;
5578
5641
  }
5579
5642
  const holder = (node) => opens.get(node.live) ?? node;
5580
- return { opening, sharedWith, know, idOf: idOf2, holder };
5643
+ return { opening, sharedWith, know, idOf: idOf3, holder };
5581
5644
  }
5582
5645
  function createHelpers(Fs, ops) {
5583
5646
  const bridgeOf = (node) => node.mount.opts.bridge;
@@ -6263,7 +6326,7 @@ function guardRenames(Fs) {
6263
6326
  rename(from, to);
6264
6327
  };
6265
6328
  }
6266
- function idOf(value2) {
6329
+ function idOf2(value2) {
6267
6330
  return value2 === -1 || value2 === 4294967295 ? void 0 : value2 >>> 0;
6268
6331
  }
6269
6332
  function useLiveChown(Fs) {
@@ -6273,7 +6336,7 @@ function useLiveChown(Fs) {
6273
6336
  const node = typeof path === "string" ? Fs.lookupPath(path, { follow: !dontFollow }).node : path;
6274
6337
  if (!node.live || node.live.orphan) return chown(path, uid, gid, dontFollow);
6275
6338
  try {
6276
- node.mount.opts.bridge.chown?.(liveNodePath(node), idOf(uid), idOf(gid));
6339
+ node.mount.opts.bridge.chown?.(liveNodePath(node), idOf2(uid), idOf2(gid));
6277
6340
  } catch (err) {
6278
6341
  throw toErrno(Fs, err);
6279
6342
  }
@@ -8420,7 +8483,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
8420
8483
  const pidContent = (target, name2, own = false) => () => {
8421
8484
  const listing = procList();
8422
8485
  const info = find(listing.processes, target, own);
8423
- if (!info) throw error(ESRCH);
8486
+ if (!info) throw error();
8424
8487
  return pidFile(name2, info, listing.boot);
8425
8488
  };
8426
8489
  const pidNames = (names) => [.../* @__PURE__ */ new Set([...names, ...PID_FILES])];
@@ -8433,14 +8496,29 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
8433
8496
  dir.node_ops.readdir = () => [".", "..", ...PID_FILES];
8434
8497
  return dir;
8435
8498
  };
8499
+ const scans = /* @__PURE__ */ new Map();
8500
+ const listed = (target) => {
8501
+ let found = false;
8502
+ for (const [stream, pids] of scans) {
8503
+ if (Fs.streams && Fs.streams[stream.fd ?? -1] !== stream) scans.delete(stream);
8504
+ else found ||= pids.has(target);
8505
+ }
8506
+ return found;
8507
+ };
8436
8508
  const procOps = proc.node_ops;
8437
8509
  const lookup = procOps.lookup?.bind(procOps);
8438
8510
  const readdir = procOps.readdir?.bind(procOps);
8511
+ const listAll = (node) => {
8512
+ const names = new Set(readdir ? readdir(node) : [".", ".."]);
8513
+ for (const name2 of [...SYSTEM_FILES, "mounts"]) names.add(name2);
8514
+ for (const p of procList().processes) names.add(String(p.pid));
8515
+ return [...names];
8516
+ };
8439
8517
  proc.node_ops = {
8440
8518
  ...procOps,
8441
8519
  lookup: (parent, name2) => {
8442
8520
  if (/^[1-9]\d*$/.test(name2)) {
8443
- if (!infoOf(Number(name2))) throw error();
8521
+ if (!infoOf(Number(name2)) && !listed(Number(name2))) throw error();
8444
8522
  return pidDir(name2, Number(name2));
8445
8523
  }
8446
8524
  if (name2 === "mounts") return file(parent, name2, () => mountTable(sys.mountList?.() ?? []));
@@ -8454,11 +8532,36 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
8454
8532
  if (!lookup) throw error();
8455
8533
  return lookup(parent, name2);
8456
8534
  },
8457
- readdir: (node) => {
8458
- const names = new Set(readdir ? readdir(node) : [".", ".."]);
8459
- for (const name2 of [...SYSTEM_FILES, "mounts"]) names.add(name2);
8460
- for (const p of procList().processes) names.add(String(p.pid));
8461
- return [...names];
8535
+ readdir: (node) => listAll(node)
8536
+ };
8537
+ const track = (stream, names) => {
8538
+ let current = names;
8539
+ const remember = (list) => scans.set(stream, new Set(list.filter((n) => /^[1-9]\d*$/.test(n)).map(Number)));
8540
+ remember(current ?? []);
8541
+ Object.defineProperty(stream, "getdents", {
8542
+ configurable: true,
8543
+ enumerable: true,
8544
+ get: () => current,
8545
+ set: (next2) => {
8546
+ current = next2;
8547
+ if (next2) remember(next2);
8548
+ }
8549
+ });
8550
+ };
8551
+ const dirOps = proc.stream_ops ?? {};
8552
+ proc.stream_ops = {
8553
+ ...dirOps,
8554
+ open: (stream) => {
8555
+ dirOps.open?.(stream);
8556
+ track(stream, listAll(proc));
8557
+ },
8558
+ dup: (stream) => {
8559
+ dirOps.dup?.(stream);
8560
+ track(stream, stream.getdents);
8561
+ },
8562
+ close: (stream) => {
8563
+ scans.delete(stream);
8564
+ dirOps.close?.(stream);
8462
8565
  }
8463
8566
  };
8464
8567
  hashRemoveNode.call(Fs, self);
@@ -8482,7 +8585,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
8482
8585
  readdir: (node) => pidNames(selfReaddir ? selfReaddir(node) : [".", ".."])
8483
8586
  };
8484
8587
  }
8485
- var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, ESRCH, EINVAL, UID2, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES, sigMask;
8588
+ var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, EINVAL, UID2, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES, sigMask;
8486
8589
  var init_procfs = __esm({
8487
8590
  "src/process/procfs.ts"() {
8488
8591
  "use strict";
@@ -8493,7 +8596,6 @@ var init_procfs = __esm({
8493
8596
  FILE_MODE = 33060;
8494
8597
  LINK_MODE2 = 41471;
8495
8598
  ENOENT = 44;
8496
- ESRCH = 71;
8497
8599
  EINVAL = 28;
8498
8600
  UID2 = 1e3;
8499
8601
  KIB = 1024;
@@ -9342,6 +9444,10 @@ function procfsBridge(fs, tree) {
9342
9444
  over[name2] = (p, ...rest2) => readOnly([[p, follow2]], () => fn.call(fs, p, ...rest2));
9343
9445
  }
9344
9446
  }
9447
+ const { chown } = fs;
9448
+ if (chown) {
9449
+ over.chown = (p, uid, gid, follow2) => readOnly([[p, follow2 === true]], () => chown.call(fs, p, uid, gid, follow2));
9450
+ }
9345
9451
  return new Proxy(fs, {
9346
9452
  get: (target, key, receiver) => key in over ? over[key] : Reflect.get(target, key, receiver)
9347
9453
  });
@@ -11727,6 +11833,9 @@ function descriptors(init, fork, threads) {
11727
11833
  if (fork) return { forked: { fds: fork.fds, cloexec: fork.cloexec } };
11728
11834
  return { inherited: init.fds ?? [], ...init.program.preopenRoot ? { preopenRoot: true } : {} };
11729
11835
  }
11836
+ function ownersOf(init) {
11837
+ return init.owners ? { owners: true } : {};
11838
+ }
11730
11839
  async function runWasiProcess(init, port3) {
11731
11840
  captureBacktraces(init.env);
11732
11841
  const signals = new WasiSignals(
@@ -11769,7 +11878,11 @@ async function runWasiProcess(init, port3) {
11769
11878
  parent: () => identify(transport, init).ppid,
11770
11879
  kernel: { sys: traced(stats, "kernel", sys), call: call2 },
11771
11880
  fs: procfsBridge(
11772
- cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport)), void 0, threads?.ids),
11881
+ cachingBridge(
11882
+ traced(stats, "fs", createSyncFsSabBridge(transport, ownersOf(init))),
11883
+ void 0,
11884
+ threads?.ids
11885
+ ),
11773
11886
  procTree(call2, id.pid)
11774
11887
  ),
11775
11888
  ...descriptors(init, fork, threads)
@@ -11863,7 +11976,7 @@ async function runWasiThread(init, port3) {
11863
11976
  parent: () => identify(transport, init).ppid,
11864
11977
  kernel: { sys, call: call2 },
11865
11978
  fs: procfsBridge(
11866
- cachingBridge(createSyncFsSabBridge(transport), void 0, threads.ids),
11979
+ cachingBridge(createSyncFsSabBridge(transport, ownersOf(init)), void 0, threads.ids),
11867
11980
  procTree(call2, id.pid)
11868
11981
  ),
11869
11982
  shared: threads.ids