@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.
@@ -603,7 +603,7 @@ function toMs(v) {
603
603
  function linkedStates(bridgeOf) {
604
604
  const opens = /* @__PURE__ */ new Map();
605
605
  const byId = /* @__PURE__ */ new Map();
606
- const idOf2 = (st) => st?.ino === void 0 || (st.nlink ?? 1) < 2 ? void 0 : `${st.dev}:${st.ino}`;
606
+ const idOf3 = (st) => st?.ino === void 0 || (st.nlink ?? 1) < 2 ? void 0 : `${st.dev}:${st.ino}`;
607
607
  function know(s, id) {
608
608
  s.id = id;
609
609
  if (!byId.has(id)) byId.set(id, s);
@@ -617,14 +617,14 @@ function linkedStates(bridgeOf) {
617
617
  return;
618
618
  }
619
619
  opens.set(s, node);
620
- const id = idOf2(s.stat);
620
+ const id = idOf3(s.stat);
621
621
  if (id !== void 0) know(s, id);
622
622
  }
623
623
  function sharedWith(node) {
624
624
  const st = node.live.stat;
625
625
  if (st?.ino === void 0) return void 0;
626
626
  const id = `${st.dev}:${st.ino}`;
627
- if (!byId.has(id) && idOf2(st) !== void 0) {
627
+ if (!byId.has(id) && idOf3(st) !== void 0) {
628
628
  for (const [s2, other] of opens) {
629
629
  if (s2.id !== void 0 || s2.orphan) continue;
630
630
  let st2;
@@ -632,7 +632,7 @@ function linkedStates(bridgeOf) {
632
632
  st2 = bridgeOf(other).lstat(liveNodePath(other));
633
633
  } catch {
634
634
  }
635
- const known = idOf2(st2);
635
+ const known = idOf3(st2);
636
636
  if (known !== void 0) know(s2, known);
637
637
  }
638
638
  }
@@ -640,7 +640,7 @@ function linkedStates(bridgeOf) {
640
640
  return s && s !== node.live && !stale(s) ? s : void 0;
641
641
  }
642
642
  const holder = (node) => opens.get(node.live) ?? node;
643
- return { opening, sharedWith, know, idOf: idOf2, holder };
643
+ return { opening, sharedWith, know, idOf: idOf3, holder };
644
644
  }
645
645
  function createHelpers(Fs, ops) {
646
646
  const bridgeOf = (node) => node.mount.opts.bridge;
@@ -1746,9 +1746,9 @@ function createSyncFsSabBridge(transport, opts = {}) {
1746
1746
  create: (path, mode) => {
1747
1747
  run({ op: "create", path, ...mode !== void 0 ? { mode } : {} }, path);
1748
1748
  },
1749
- chown: (path, uid, gid) => {
1749
+ chown: (path, uid, gid, follow2) => {
1750
1750
  const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
1751
- run({ op: "lchown", path, ...ids }, path);
1751
+ run({ op: follow2 ? "chown" : "lchown", path, ...ids }, path);
1752
1752
  },
1753
1753
  ...opts.owners ? { owners: true } : {},
1754
1754
  hold: (path, held, open, handle) => {
@@ -3850,7 +3850,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3850
3850
  const pidContent = (target, name2, own = false) => () => {
3851
3851
  const listing = procList();
3852
3852
  const info = find(listing.processes, target, own);
3853
- if (!info) throw error(ESRCH);
3853
+ if (!info) throw error();
3854
3854
  return pidFile(name2, info, listing.boot);
3855
3855
  };
3856
3856
  const pidNames = (names) => [.../* @__PURE__ */ new Set([...names, ...PID_FILES])];
@@ -3863,14 +3863,29 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3863
3863
  dir.node_ops.readdir = () => [".", "..", ...PID_FILES];
3864
3864
  return dir;
3865
3865
  };
3866
+ const scans = /* @__PURE__ */ new Map();
3867
+ const listed = (target) => {
3868
+ let found = false;
3869
+ for (const [stream, pids] of scans) {
3870
+ if (Fs.streams && Fs.streams[stream.fd ?? -1] !== stream) scans.delete(stream);
3871
+ else found ||= pids.has(target);
3872
+ }
3873
+ return found;
3874
+ };
3866
3875
  const procOps = proc.node_ops;
3867
3876
  const lookup = procOps.lookup?.bind(procOps);
3868
3877
  const readdir = procOps.readdir?.bind(procOps);
3878
+ const listAll = (node) => {
3879
+ const names = new Set(readdir ? readdir(node) : [".", ".."]);
3880
+ for (const name2 of [...SYSTEM_FILES, "mounts"]) names.add(name2);
3881
+ for (const p of procList().processes) names.add(String(p.pid));
3882
+ return [...names];
3883
+ };
3869
3884
  proc.node_ops = {
3870
3885
  ...procOps,
3871
3886
  lookup: (parent, name2) => {
3872
3887
  if (/^[1-9]\d*$/.test(name2)) {
3873
- if (!infoOf(Number(name2))) throw error();
3888
+ if (!infoOf(Number(name2)) && !listed(Number(name2))) throw error();
3874
3889
  return pidDir(name2, Number(name2));
3875
3890
  }
3876
3891
  if (name2 === "mounts") return file(parent, name2, () => mountTable(sys.mountList?.() ?? []));
@@ -3884,11 +3899,36 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3884
3899
  if (!lookup) throw error();
3885
3900
  return lookup(parent, name2);
3886
3901
  },
3887
- readdir: (node) => {
3888
- const names = new Set(readdir ? readdir(node) : [".", ".."]);
3889
- for (const name2 of [...SYSTEM_FILES, "mounts"]) names.add(name2);
3890
- for (const p of procList().processes) names.add(String(p.pid));
3891
- return [...names];
3902
+ readdir: (node) => listAll(node)
3903
+ };
3904
+ const track = (stream, names) => {
3905
+ let current = names;
3906
+ const remember = (list) => scans.set(stream, new Set(list.filter((n) => /^[1-9]\d*$/.test(n)).map(Number)));
3907
+ remember(current ?? []);
3908
+ Object.defineProperty(stream, "getdents", {
3909
+ configurable: true,
3910
+ enumerable: true,
3911
+ get: () => current,
3912
+ set: (next2) => {
3913
+ current = next2;
3914
+ if (next2) remember(next2);
3915
+ }
3916
+ });
3917
+ };
3918
+ const dirOps = proc.stream_ops ?? {};
3919
+ proc.stream_ops = {
3920
+ ...dirOps,
3921
+ open: (stream) => {
3922
+ dirOps.open?.(stream);
3923
+ track(stream, listAll(proc));
3924
+ },
3925
+ dup: (stream) => {
3926
+ dirOps.dup?.(stream);
3927
+ track(stream, stream.getdents);
3928
+ },
3929
+ close: (stream) => {
3930
+ scans.delete(stream);
3931
+ dirOps.close?.(stream);
3892
3932
  }
3893
3933
  };
3894
3934
  hashRemoveNode.call(Fs, self);
@@ -3912,7 +3952,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
3912
3952
  readdir: (node) => pidNames(selfReaddir ? selfReaddir(node) : [".", ".."])
3913
3953
  };
3914
3954
  }
3915
- var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, ESRCH, EINVAL, UID, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES, sigMask;
3955
+ var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, EINVAL, UID, KIB, FALLBACK_MEMORY, PID_FILES, SYSTEM_FILES, sigMask;
3916
3956
  var init_procfs = __esm({
3917
3957
  "src/process/procfs.ts"() {
3918
3958
  "use strict";
@@ -3923,7 +3963,6 @@ var init_procfs = __esm({
3923
3963
  FILE_MODE = 33060;
3924
3964
  LINK_MODE2 = 41471;
3925
3965
  ENOENT = 44;
3926
- ESRCH = 71;
3927
3966
  EINVAL = 28;
3928
3967
  UID = 1e3;
3929
3968
  KIB = 1024;
@@ -4670,6 +4709,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
4670
4709
  };
4671
4710
  const invalidate = () => cache.mutated([]);
4672
4711
  const touched = (path, ino) => cache.changed(path, ino);
4712
+ const { chown } = bridge;
4673
4713
  const mutating = (op, ...paths) => {
4674
4714
  try {
4675
4715
  return op();
@@ -4725,11 +4765,15 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
4725
4765
  ...bridge.kept ? { kept: bridge.kept.bind(bridge) } : {},
4726
4766
  ...bridge.pinned ? { pinned: (handle) => pinnedIo2(bridge, handle, rewriting) } : {},
4727
4767
  ...bridge.create ? { create: (p) => mutating(() => bridge.create?.(p), ...entry(p)) } : {},
4768
+ ...chown ? {
4769
+ chown: (p, uid, gid, follow2) => rewriting(p, () => chown.call(bridge, p, uid, gid, follow2))
4770
+ } : {},
4728
4771
  ...bridge.pread && bridge.pwrite && bridge.truncate ? {
4729
4772
  pread: bridge.pread.bind(bridge),
4730
4773
  pwrite: (p, at, bytes, transfer) => rewriting(p, () => bridge.pwrite?.(p, at, bytes, transfer)),
4731
4774
  truncate: (p, size) => rewriting(p, () => bridge.truncate?.(p, size))
4732
4775
  } : {},
4776
+ ...bridge.owners ? { owners: true } : {},
4733
4777
  invalidate,
4734
4778
  touched
4735
4779
  };
@@ -5970,6 +6014,9 @@ var init_wasi_termios = __esm({
5970
6014
  });
5971
6015
 
5972
6016
  // src/process/wasi/wasi-host.ts
6017
+ function idOf2(value2) {
6018
+ return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
6019
+ }
5973
6020
  function linkedOf(st) {
5974
6021
  return (st.nlink ?? 1) > 1 ? st : void 0;
5975
6022
  }
@@ -6038,7 +6085,7 @@ function wrap(table) {
6038
6085
  }
6039
6086
  return out;
6040
6087
  }
6041
- var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
6088
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
6042
6089
  var init_wasi_host = __esm({
6043
6090
  "src/process/wasi/wasi-host.ts"() {
6044
6091
  "use strict";
@@ -6060,6 +6107,8 @@ var init_wasi_host = __esm({
6060
6107
  IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
6061
6108
  NS_PER_MS = 1000000n;
6062
6109
  AT_SYMLINK_NOFOLLOW2 = 1;
6110
+ ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
6111
+ GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
6063
6112
  S_IFIFO = 4096;
6064
6113
  DEFAULT_UMASK = 18;
6065
6114
  MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
@@ -6131,7 +6180,60 @@ var init_wasi_host = __esm({
6131
6180
  return path;
6132
6181
  };
6133
6182
  const modeOf = (st) => (st.mode ?? 0) & 4095;
6183
+ const chown = (path, uid, gid, follow2) => {
6184
+ const { chown: own } = this.o.fs;
6185
+ if (!own) throw new WasiError("ENOSYS");
6186
+ own.call(this.o.fs, path, idOf2(uid), idOf2(gid), follow2);
6187
+ };
6188
+ const caller = () => {
6189
+ const cred = this.o.kernel.call({ op: "proc-cred" });
6190
+ return [cred.euid, cred.egid];
6191
+ };
6192
+ const owner = (st, out) => {
6193
+ const [uid, gid] = st?.uid === void 0 ? caller() : [st.uid, st.gid];
6194
+ const view = mem.view();
6195
+ view.getUint32(out + 4, true);
6196
+ view.setUint32(out, uid, true);
6197
+ view.setUint32(out + 4, gid, true);
6198
+ };
6199
+ const fdOwned = (fd) => {
6200
+ const e = fds.get(fd);
6201
+ if (e.type === "device") return ROOT_IDS;
6202
+ if (e.type === "kernel" && fds.kind(fd, e) !== "file") return void 0;
6203
+ try {
6204
+ return this.o.fs.stat(pathOf(fd));
6205
+ } catch (err) {
6206
+ if (!GONE.has(err?.code)) throw err;
6207
+ return void 0;
6208
+ }
6209
+ };
6210
+ const pathOwned = (path, follow2) => {
6211
+ if (deviceOf(path)) return ROOT_IDS;
6212
+ return follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
6213
+ };
6134
6214
  return wrap({
6215
+ fd_chown: (fd, uid, gid) => void chown(pathOf(fd), uid, gid, true),
6216
+ path_chown: (dirfd, p, l, uid, gid, flags) => void chown(at(dirfd, p, l), uid, gid, (flags & AT_SYMLINK_NOFOLLOW2) === 0),
6217
+ fd_owner: (fd, out) => {
6218
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
6219
+ owner(fdOwned(fd), out);
6220
+ },
6221
+ fd_filestat_owner: (fd, statOut, out) => {
6222
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
6223
+ this.writeFilestat(statOut, this.fdFilestat(fd));
6224
+ owner(fdOwned(fd), out);
6225
+ },
6226
+ path_filestat_owner: (dirfd, lookup, p, l, statOut, out) => {
6227
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
6228
+ const path = at(dirfd, p, l);
6229
+ this.writeFilestat(statOut, this.pathFilestat(path, lookup));
6230
+ owner(pathOwned(path, (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
6231
+ },
6232
+ path_owner: (dirfd, p, l, flags, out) => {
6233
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
6234
+ const path = at(dirfd, p, l);
6235
+ owner(pathOwned(path, (flags & AT_SYMLINK_NOFOLLOW2) === 0), out);
6236
+ },
6135
6237
  fd_chmod: (fd, mode) => void this.o.fs.chmod(pathOf(fd), mode & 4095),
6136
6238
  path_chmod: (dirfd, p, l, mode, flags) => void this.o.fs.chmod(target(at(dirfd, p, l), flags), mode & 4095),
6137
6239
  umask: (mask, out) => {
@@ -7427,6 +7529,10 @@ function procfsBridge(fs, tree) {
7427
7529
  over[name2] = (p, ...rest2) => readOnly([[p, follow2]], () => fn.call(fs, p, ...rest2));
7428
7530
  }
7429
7531
  }
7532
+ const { chown } = fs;
7533
+ if (chown) {
7534
+ over.chown = (p, uid, gid, follow2) => readOnly([[p, follow2 === true]], () => chown.call(fs, p, uid, gid, follow2));
7535
+ }
7430
7536
  return new Proxy(fs, {
7431
7537
  get: (target, key, receiver) => key in over ? over[key] : Reflect.get(target, key, receiver)
7432
7538
  });
@@ -9812,6 +9918,9 @@ function descriptors(init, fork, threads) {
9812
9918
  if (fork) return { forked: { fds: fork.fds, cloexec: fork.cloexec } };
9813
9919
  return { inherited: init.fds ?? [], ...init.program.preopenRoot ? { preopenRoot: true } : {} };
9814
9920
  }
9921
+ function ownersOf(init) {
9922
+ return init.owners ? { owners: true } : {};
9923
+ }
9815
9924
  async function runWasiProcess(init, port2) {
9816
9925
  captureBacktraces(init.env);
9817
9926
  const signals = new WasiSignals(
@@ -9854,7 +9963,11 @@ async function runWasiProcess(init, port2) {
9854
9963
  parent: () => identify(transport, init).ppid,
9855
9964
  kernel: { sys: traced(stats, "kernel", sys), call: call2 },
9856
9965
  fs: procfsBridge(
9857
- cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport)), void 0, threads?.ids),
9966
+ cachingBridge(
9967
+ traced(stats, "fs", createSyncFsSabBridge(transport, ownersOf(init))),
9968
+ void 0,
9969
+ threads?.ids
9970
+ ),
9858
9971
  procTree(call2, id.pid)
9859
9972
  ),
9860
9973
  ...descriptors(init, fork, threads)
@@ -9948,7 +10061,7 @@ async function runWasiThread(init, port2) {
9948
10061
  parent: () => identify(transport, init).ppid,
9949
10062
  kernel: { sys, call: call2 },
9950
10063
  fs: procfsBridge(
9951
- cachingBridge(createSyncFsSabBridge(transport), void 0, threads.ids),
10064
+ cachingBridge(createSyncFsSabBridge(transport, ownersOf(init)), void 0, threads.ids),
9952
10065
  procTree(call2, id.pid)
9953
10066
  ),
9954
10067
  shared: threads.ids