@ai-ecoverse/slicc-kernel 1.85.0 → 1.86.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.
@@ -1112,10 +1112,14 @@ function liveNodePath(node) {
1112
1112
  const root = node.mount.opts.root.replace(/\/+$/, "");
1113
1113
  return parts.length === 0 ? root || "/" : `${root}/${parts.reverse().join("/")}`;
1114
1114
  }
1115
- function modeFromStat(st) {
1115
+ function exactIn(node) {
1116
+ return node?.mount.opts.bridge.owners === true;
1117
+ }
1118
+ function modeFromStat(st, exact = false) {
1116
1119
  const type = st.isSymbolicLink ? S_IFLNK : st.isDirectory ? S_IFDIR : S_IFREG;
1117
1120
  const fallback = st.isDirectory || st.isSymbolicLink ? 511 : 438;
1118
- return type | ((st.mode ?? fallback) & PERM_MASK || fallback);
1121
+ const perm = (st.mode ?? fallback) & PERM_MASK;
1122
+ return type | (exact ? perm : perm || fallback);
1119
1123
  }
1120
1124
  function toMs(v) {
1121
1125
  if (v === void 0 || v === null) return void 0;
@@ -1223,7 +1227,7 @@ function createHelpers(Fs, ops) {
1223
1227
  return { ...stat ? { stat, statAt } : {}, len: 0, loaded: false, dirty: false, openCount: 0 };
1224
1228
  }
1225
1229
  function makeNode(parent, name2, st) {
1226
- const node = Fs.createNode(parent, name2, modeFromStat(st), 0);
1230
+ const node = Fs.createNode(parent, name2, modeFromStat(st, exactIn(parent)), 0);
1227
1231
  node.node_ops = ops.node;
1228
1232
  node.stream_ops = ops.stream;
1229
1233
  node.live = freshState(st);
@@ -1237,7 +1241,7 @@ function createHelpers(Fs, ops) {
1237
1241
  if (!cachedStat(node.live, Fs.isDir(node.mode))) {
1238
1242
  const st = call2(() => bridgeOf(node).lstat(liveNodePath(linked.holder(node))));
1239
1243
  Object.assign(node.live, { stat: st, statAt: syncCallCount() });
1240
- node.mode = modeFromStat(st);
1244
+ node.mode = modeFromStat(st, exactIn(node));
1241
1245
  }
1242
1246
  return node.live.stat;
1243
1247
  }
@@ -1575,9 +1579,21 @@ function createStreamOps(h) {
1575
1579
  }
1576
1580
  return want;
1577
1581
  };
1582
+ const directory = (stream) => {
1583
+ const bridge = bridgeOf(stream.node);
1584
+ if (!bridge.owners || !Fs.isDir(stream.node.mode) || stream.flags & O_PATH) return;
1585
+ try {
1586
+ h.call(
1587
+ () => bridge.access?.(liveNodePath(stream.node), accessOf(wantOf(stream.flags)), "open")
1588
+ );
1589
+ } catch (err) {
1590
+ if (stream.fd !== void 0) Fs.closeStream?.(stream.fd);
1591
+ throw err;
1592
+ }
1593
+ };
1578
1594
  return {
1579
1595
  open(stream) {
1580
- if (!Fs.isFile(stream.node.mode)) return;
1596
+ if (!Fs.isFile(stream.node.mode)) return directory(stream);
1581
1597
  const s = stream.node.live;
1582
1598
  const created = s.created === true;
1583
1599
  s.created = void 0;
@@ -1709,6 +1725,7 @@ function createLiveVfsPlugin(Fs) {
1709
1725
  const st = h.call(() => mount.opts.bridge.stat(mount.opts.root));
1710
1726
  if (!st.isDirectory) throw new Fs.ErrnoError(wasiErrno("ENOTDIR"));
1711
1727
  const root = h.makeNode(null, "/", st);
1728
+ root.mode = modeFromStat(st, mount.opts.bridge.owners === true);
1712
1729
  mounts.add(mount);
1713
1730
  return root;
1714
1731
  }
@@ -1918,7 +1935,7 @@ function useLiveChown(Fs) {
1918
1935
  Fs.chown(target, uid, gid);
1919
1936
  };
1920
1937
  }
1921
- var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_ACCMODE, O_TRUNC, stale;
1938
+ 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;
1922
1939
  var init_live_vfs_fs = __esm({
1923
1940
  "src/realm/live-vfs-fs.ts"() {
1924
1941
  "use strict";
@@ -1938,6 +1955,7 @@ var init_live_vfs_fs = __esm({
1938
1955
  EARLY_WHOLE_FILE = 64 * 1024;
1939
1956
  O_ACCMODE = 3;
1940
1957
  O_TRUNC = 512;
1958
+ O_PATH = 2097152;
1941
1959
  stale = (s) => !!s.orphan && !s.kept;
1942
1960
  }
1943
1961
  });
@@ -2757,7 +2775,7 @@ function pathOpensLinks(Fs) {
2757
2775
  const fs = Fs;
2758
2776
  const { mayOpen, isLink } = fs;
2759
2777
  if (!mayOpen || !isLink) return;
2760
- fs.mayOpen = (node, flags) => flags & O_PATH && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
2778
+ fs.mayOpen = (node, flags) => flags & O_PATH2 && isLink.call(fs, node.mode) ? 0 : mayOpen.call(fs, node, flags);
2761
2779
  }
2762
2780
  function importKey(namespace, name2, glue) {
2763
2781
  const own = glue?.[name2];
@@ -3237,7 +3255,24 @@ function kernelAccess(imports, fs, memory, glue) {
3237
3255
  }
3238
3256
  });
3239
3257
  }
3258
+ function kernelChdir(Fs) {
3259
+ const { chdir, lookupPath, ErrnoError } = Fs;
3260
+ if (!chdir || !lookupPath || !ErrnoError) return;
3261
+ Fs.chdir = (path) => {
3262
+ const { node } = lookupPath.call(Fs, path, { follow: true });
3263
+ const directory = Fs.isDir?.(node.mode) === true;
3264
+ const bridge = node.live && directory ? node.mount.opts.bridge : void 0;
3265
+ try {
3266
+ bridge?.access?.(liveNodePath(node), X_ACCESS, "eaccess", false);
3267
+ } catch (err) {
3268
+ throw new ErrnoError(errnoOf(err));
3269
+ }
3270
+ chdir.call(Fs, path);
3271
+ };
3272
+ }
3240
3273
  function linuxDevices(Fs) {
3274
+ Fs.ignorePermissions = true;
3275
+ kernelChdir(Fs);
3241
3276
  const { chmod } = Fs;
3242
3277
  if (!chmod) return;
3243
3278
  for (const [path, mode] of DEVICE_MODES) {
@@ -3247,7 +3282,7 @@ function linuxDevices(Fs) {
3247
3282
  }
3248
3283
  }
3249
3284
  }
3250
- 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_PATH, 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, DEVICE_MODES;
3285
+ 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, DEVICE_MODES;
3251
3286
  var init_process_fds = __esm({
3252
3287
  "src/process/process-fds.ts"() {
3253
3288
  "use strict";
@@ -3275,7 +3310,7 @@ var init_process_fds = __esm({
3275
3310
  EBADF = 8;
3276
3311
  AT_SYMLINK_NOFOLLOW = 256;
3277
3312
  EMSCRIPTEN_EPERM = 63;
3278
- O_PATH = 2097152;
3313
+ O_PATH2 = 2097152;
3279
3314
  LITERALS = {
3280
3315
  openat: "__syscall_openat",
3281
3316
  mkdirat: "__syscall_mkdirat",
@@ -3307,6 +3342,7 @@ var init_process_fds = __esm({
3307
3342
  AT_FDCWD = -100;
3308
3343
  AT_EACCESS = 512;
3309
3344
  W_ACCESS = 2;
3345
+ X_ACCESS = 1;
3310
3346
  DEVICE_MODES = [
3311
3347
  ["/", 493],
3312
3348
  ["/dev", 493],
@@ -6904,7 +6940,7 @@ var init_wasi_host = __esm({
6904
6940
  }
6905
6941
  return path;
6906
6942
  };
6907
- const modeOf = (st) => (st.mode ?? 0) & 4095;
6943
+ const modeOf2 = (st) => (st.mode ?? 0) & 4095;
6908
6944
  const chown = (path, uid, gid, follow2) => {
6909
6945
  const { chown: own } = this.o.fs;
6910
6946
  if (!own) throw new WasiError("ENOSYS");
@@ -6983,7 +7019,7 @@ var init_wasi_host = __esm({
6983
7019
  fd_mode: (fd, out) => {
6984
7020
  const e = fds.get(fd);
6985
7021
  const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
6986
- const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
7022
+ const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf2(this.o.fs.stat(pathOf(fd)));
6987
7023
  mem.view().setUint32(out, mode, true);
6988
7024
  },
6989
7025
  path_mode: (dirfd, p, l, flags, out) => {
@@ -6991,7 +7027,7 @@ var init_wasi_host = __esm({
6991
7027
  if (this.synthetic(path) && deviceOf(path) === void 0)
6992
7028
  return void mem.view().setUint32(out, SEALED_MODE, true);
6993
7029
  const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
6994
- mem.view().setUint32(out, modeOf(st), true);
7030
+ mem.view().setUint32(out, modeOf2(st), true);
6995
7031
  }
6996
7032
  });
6997
7033
  }
@@ -11088,6 +11124,12 @@ var init_async_sab = __esm({
11088
11124
  });
11089
11125
 
11090
11126
  // src/process/js/js-kernel.ts
11127
+ function modeOf(mode) {
11128
+ if (!Number.isInteger(mode) || mode < 0 || mode > 4095) {
11129
+ throw new JsCallError("EINVAL", "chmod");
11130
+ }
11131
+ return mode;
11132
+ }
11091
11133
  function callError(result, op) {
11092
11134
  const { errno: errno2, message: message2 } = result;
11093
11135
  const detailed = typeof message2 === "string" && message2 !== errno2 && DETAILED.has(op);
@@ -12700,10 +12742,15 @@ function syncPathOps(kernel, resolve, statOf, open) {
12700
12742
  if (inDev(abs)) return devSync(kernel, devReaddir(abs));
12701
12743
  return kernel.json({ op: "readdir", path: abs });
12702
12744
  },
12703
- mkdir: (path) => void kernel.call({ op: "mkdir", path: resolve(path) }),
12745
+ mkdir: (path, options) => void kernel.call({
12746
+ op: "mkdir",
12747
+ path: resolve(path),
12748
+ ...options?.recursive === false ? { exclusive: true } : {}
12749
+ }),
12704
12750
  rm: (path) => void kernel.call({ op: "rm", path: resolve(path) }),
12705
12751
  unlink: (path) => void kernel.call({ op: "unlink", path: resolve(path) }),
12706
12752
  rename: (from, to) => void kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
12753
+ chmod: (path, mode) => void kernel.call({ op: "chmod", path: resolve(path), mode: modeOf(mode) }),
12707
12754
  link: (from, to) => void kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
12708
12755
  symlink: (target, path) => void kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
12709
12756
  readlink(path) {
@@ -13206,7 +13253,9 @@ function createContext(o) {
13206
13253
  kill: killer({ self: o.pid, kernel, syncKernel, lane, writes, modes: terminal.modes }),
13207
13254
  cred: () => syncKernel.json({ op: "proc-cred" }),
13208
13255
  setcred(change) {
13209
- if (typeof change !== "object" || change === null) throw new JsCallError("EINVAL", "setcred");
13256
+ if (typeof change !== "object" || change === null || Array.isArray(change)) {
13257
+ throw new JsCallError("EINVAL", "setcred");
13258
+ }
13210
13259
  return syncKernel.json({ op: "proc-setcred", change: { ...change } });
13211
13260
  }
13212
13261
  };
@@ -13402,10 +13451,15 @@ function pathOps(kernel, resolve, statOf, open) {
13402
13451
  if (inDev(abs)) return devAsync(kernel, devReaddir(abs));
13403
13452
  return await kernel.json({ op: "readdir", path: abs });
13404
13453
  },
13405
- mkdir: async (path) => void await kernel.call({ op: "mkdir", path: resolve(path) }),
13454
+ mkdir: async (path, options) => void await kernel.call({
13455
+ op: "mkdir",
13456
+ path: resolve(path),
13457
+ ...options?.recursive === false ? { exclusive: true } : {}
13458
+ }),
13406
13459
  rm: async (path) => void await kernel.call({ op: "rm", path: resolve(path) }),
13407
13460
  unlink: async (path) => void await kernel.call({ op: "unlink", path: resolve(path) }),
13408
13461
  rename: async (from, to) => void await kernel.call({ op: "rename", path: resolve(from), arg2: resolve(to) }),
13462
+ chmod: async (path, mode) => void await kernel.call({ op: "chmod", path: resolve(path), mode: modeOf(mode) }),
13409
13463
  link: async (from, to) => void await kernel.call({ op: "link", path: resolve(from), arg2: resolve(to) }),
13410
13464
  symlink: async (target, path) => void await kernel.call({ op: "symlink", path: resolve(path), arg2: target }),
13411
13465
  async readlink(path) {