@ai-ecoverse/slicc-kernel 1.56.1 → 1.57.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.
@@ -786,6 +786,7 @@ function createNodeOps(h) {
786
786
  return {
787
787
  getattr(node) {
788
788
  const st = statOf(node);
789
+ const owned = bridgeOf(node).owners === true;
789
790
  const s = node.live;
790
791
  const size = Fs.isDir(node.mode) ? 4096 : s.ranged?.size() ?? (s.loaded ? s.len : st.size);
791
792
  const mtime = new Date(st.mtimeMs ?? 0);
@@ -794,8 +795,8 @@ function createNodeOps(h) {
794
795
  ino: st.ino ?? inodeOf(liveNodePath(node)),
795
796
  mode: node.mode,
796
797
  nlink: 1,
797
- uid: 0,
798
- gid: 0,
798
+ uid: owned ? st.uid ?? 0 : 0,
799
+ gid: owned ? st.gid ?? 0 : 0,
799
800
  rdev: 0,
800
801
  size,
801
802
  atime: new Date(st.atimeMs ?? mtime.getTime()),
@@ -838,14 +839,17 @@ function createNodeOps(h) {
838
839
  mknod(parent, name2, mode) {
839
840
  parent.live.listed = void 0;
840
841
  const path = childPath(parent, name2);
841
- if (Fs.isDir(mode)) {
842
- call2(() => bridgeOf(parent).mkdir(path));
843
- const perm = mode & PERM_MASK & ~UMASK;
844
- if (perm !== DEFAULT_DIR_PERM) metadataCall(() => bridgeOf(parent).chmod(path, perm));
842
+ const bridge = bridgeOf(parent);
843
+ const perm = bridge.owners ? mode & PERM_MASK : void 0;
844
+ if (Fs.isDir(mode) && perm !== void 0) {
845
+ call2(() => bridge.mkdir(path, perm));
846
+ } else if (Fs.isDir(mode)) {
847
+ call2(() => bridge.mkdir(path));
848
+ const masked = mode & PERM_MASK & ~UMASK;
849
+ if (masked !== DEFAULT_DIR_PERM) metadataCall(() => bridge.chmod(path, masked));
845
850
  } else if (Fs.isFile(mode)) {
846
- const bridge = bridgeOf(parent);
847
851
  call2(
848
- () => bridge.create ? bridge.create(path) : bridge.writeFile(path, new Uint8Array(0))
852
+ () => bridge.create ? bridge.create(path, perm) : bridge.writeFile(path, new Uint8Array(0))
849
853
  );
850
854
  } else {
851
855
  throw new Fs.ErrnoError(wasiErrno("EPERM"));
@@ -1248,6 +1252,32 @@ function guardRenames(Fs) {
1248
1252
  rename(from, to);
1249
1253
  };
1250
1254
  }
1255
+ function idOf(value2) {
1256
+ return value2 === -1 || value2 === 4294967295 ? void 0 : value2 >>> 0;
1257
+ }
1258
+ function useLiveChown(Fs) {
1259
+ const chown = Fs.chown?.bind(Fs);
1260
+ if (!chown) return;
1261
+ Fs.chown = (path, uid, gid, dontFollow) => {
1262
+ const node = typeof path === "string" ? Fs.lookupPath(path, { follow: !dontFollow }).node : path;
1263
+ if (!node.live || node.live.orphan) return chown(path, uid, gid, dontFollow);
1264
+ try {
1265
+ node.mount.opts.bridge.chown?.(liveNodePath(node), idOf(uid), idOf(gid));
1266
+ } catch (err) {
1267
+ throw toErrno(Fs, err);
1268
+ }
1269
+ node.live.stat = void 0;
1270
+ if (node.parent?.live) node.parent.live.listed = void 0;
1271
+ };
1272
+ const { getStreamChecked } = Fs;
1273
+ if (!Fs.fchown || !getStreamChecked) return;
1274
+ Fs.fchown = (fd, uid, gid) => {
1275
+ const stream = getStreamChecked.call(Fs, fd);
1276
+ const live = stream.node.live !== void 0;
1277
+ const target = live || stream.path === void 0 ? stream.node : stream.path;
1278
+ Fs.chown(target, uid, gid);
1279
+ };
1280
+ }
1251
1281
  var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE;
1252
1282
  var init_live_vfs_fs = __esm({
1253
1283
  "src/realm/live-vfs-fs.ts"() {
@@ -1292,6 +1322,7 @@ function mountVfsIntoEmscripten(Fs, deps) {
1292
1322
  const dirs = topLevelDirs(bridge, warn);
1293
1323
  const { plugin, mounted } = mountLiveVfsDirs(Fs, bridge, dirs ?? [], warn);
1294
1324
  if (dirs) liveRoot(Fs, bridge);
1325
+ if (bridge.owners && Fs.lookupPath) useLiveChown(Fs);
1295
1326
  try {
1296
1327
  Fs.chdir(deps.cwd);
1297
1328
  } catch (err) {
@@ -1342,7 +1373,9 @@ function parseSyncFsStat(json) {
1342
1373
  ...s.readonly === true ? { readonly: true } : {},
1343
1374
  ...typeof s.maxFile === "number" ? { maxFile: s.maxFile } : {},
1344
1375
  ...s.ranged === true ? { ranged: true } : {},
1345
- ...typeof s.version === "string" ? { version: s.version } : {}
1376
+ ...typeof s.version === "string" ? { version: s.version } : {},
1377
+ ...typeof s.uid === "number" ? { uid: s.uid } : {},
1378
+ ...typeof s.gid === "number" ? { gid: s.gid } : {}
1346
1379
  };
1347
1380
  }
1348
1381
  var SYNC_FS_OPS, SYNC_FS_REQUEST_TIMEOUT_MS;
@@ -1373,7 +1406,9 @@ var init_sync_fs_wire = __esm({
1373
1406
  "kept",
1374
1407
  "pread",
1375
1408
  "pwrite",
1376
- "truncate"
1409
+ "truncate",
1410
+ "chown",
1411
+ "lchown"
1377
1412
  ];
1378
1413
  SYNC_FS_REQUEST_TIMEOUT_MS = 25e3;
1379
1414
  }
@@ -1595,8 +1630,8 @@ function createSyncFsSabBridge(transport, opts = {}) {
1595
1630
  if (typeof v !== "boolean") throw errnoError("EIO", path);
1596
1631
  return v;
1597
1632
  },
1598
- mkdir: (path) => {
1599
- run({ op: "mkdir", path }, path);
1633
+ mkdir: (path, mode) => {
1634
+ run({ op: "mkdir", path, ...mode !== void 0 ? { mode } : {} }, path);
1600
1635
  },
1601
1636
  rm: (path) => {
1602
1637
  run({ op: "rm", path }, path);
@@ -1627,9 +1662,14 @@ function createSyncFsSabBridge(transport, opts = {}) {
1627
1662
  lutimes: (path, atimeMs, mtimeMs) => {
1628
1663
  run({ op: "lutimes", path, atimeMs, mtimeMs }, path);
1629
1664
  },
1630
- create: (path) => {
1631
- run({ op: "create", path }, path);
1665
+ create: (path, mode) => {
1666
+ run({ op: "create", path, ...mode !== void 0 ? { mode } : {} }, path);
1667
+ },
1668
+ chown: (path, uid, gid) => {
1669
+ const ids = { ...uid !== void 0 ? { uid } : {}, ...gid !== void 0 ? { gid } : {} };
1670
+ run({ op: "lchown", path, ...ids }, path);
1632
1671
  },
1672
+ ...opts.owners ? { owners: true } : {},
1633
1673
  hold: (path, held, open, handle) => {
1634
1674
  const mode = (held ? 1 : 0) | (open ? 2 : 0);
1635
1675
  if (mode === 3) return json({ op: "hold", path, mode }, path);
@@ -4049,6 +4089,9 @@ function reportGrowth(imports, publish) {
4049
4089
  return grown;
4050
4090
  };
4051
4091
  }
4092
+ function callerOwner(Fs, init) {
4093
+ return init.owners ? {} : { owner: ownByCaller(Fs, init.cred, credAbi(init.program.glue)) };
4094
+ }
4052
4095
  async function runWasmProcess(init, port2, deps = {}) {
4053
4096
  const signals = new SignalGate(
4054
4097
  createSyncSabTransport(init.sab, port2, {
@@ -4159,7 +4202,7 @@ async function runWasmProcess(init, port2, deps = {}) {
4159
4202
  const running = module;
4160
4203
  if (!hasStreams(running)) return runStdioOnly(running, init);
4161
4204
  const vfs = mountVfsIntoEmscripten(running.FS, {
4162
- bridge: createSyncFsSabBridge(transport),
4205
+ bridge: createSyncFsSabBridge(transport, init.owners ? { owners: true } : {}),
4163
4206
  cwd: init.cwd,
4164
4207
  warn: deps.warn ?? say(2)
4165
4208
  });
@@ -4201,7 +4244,7 @@ async function runWasmProcess(init, port2, deps = {}) {
4201
4244
  describeFork: () => describeForFork(running.FS, sys, streams, livePath),
4202
4245
  inherit: (actions) => describeInherited(running.FS, sys, streams, livePath, actions),
4203
4246
  stdioPromoter: () => vfsPromoter(running.FS, sys, streams, livePath),
4204
- owner: ownByCaller(running.FS, init.cred, credAbi(init.program.glue))
4247
+ ...callerOwner(running.FS, init)
4205
4248
  });
4206
4249
  running.sliccKernel.http = createHttpKernel(transport);
4207
4250
  running.sliccKernel.hostname = hostnameOf(init.env);
@@ -4472,6 +4515,35 @@ function normalize(path) {
4472
4515
  }
4473
4516
  return `/${out.join("/")}`;
4474
4517
  }
4518
+ function physical(fs, path) {
4519
+ let done = [];
4520
+ let todo = path.split("/").filter((part) => part !== "" && part !== ".");
4521
+ let hops = 0;
4522
+ while (todo.length > 0) {
4523
+ const part = todo.shift();
4524
+ if (part === "..") {
4525
+ done.pop();
4526
+ continue;
4527
+ }
4528
+ if (!todo.includes("..")) {
4529
+ done.push(part);
4530
+ continue;
4531
+ }
4532
+ const at = `/${[...done, part].join("/")}`;
4533
+ const st = fs.lstat(at);
4534
+ if (st.isSymbolicLink) {
4535
+ if (++hops > MAX_LINKS) throw new WasiError("ELOOP");
4536
+ const target = fs.readlink(at);
4537
+ if (target.startsWith("/")) done = [];
4538
+ todo = [...target.split("/").filter((p) => p !== "" && p !== "."), ...todo];
4539
+ } else if (!st.isDirectory) {
4540
+ throw new WasiError("ENOTDIR");
4541
+ } else {
4542
+ done.push(part);
4543
+ }
4544
+ }
4545
+ return `/${done.join("/")}`;
4546
+ }
4475
4547
  function resolveUnder(dir, path) {
4476
4548
  return normalize(path.startsWith("/") ? path : `${dir}/${path}`);
4477
4549
  }
@@ -4567,7 +4639,7 @@ function pinnedIo2(bridge, handle, mutating) {
4567
4639
  truncate: (p, size) => mutating(() => truncate(p, size))
4568
4640
  };
4569
4641
  }
4570
- var WasiError, FileBuffer, LocalFile, MISS_TTL_MS;
4642
+ var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS;
4571
4643
  var init_wasi_files = __esm({
4572
4644
  "src/process/wasi/wasi-files.ts"() {
4573
4645
  "use strict";
@@ -4755,6 +4827,7 @@ var init_wasi_files = __esm({
4755
4827
  this.buffer.flush();
4756
4828
  }
4757
4829
  };
4830
+ MAX_LINKS = 40;
4758
4831
  MISS_TTL_MS = 20;
4759
4832
  }
4760
4833
  });
@@ -5220,8 +5293,8 @@ var init_wasi_fds = __esm({
5220
5293
  }
5221
5294
  }
5222
5295
  resolve(dirfd, path) {
5223
- if (path.startsWith("/")) return normalize(path);
5224
- return resolveUnder(this.dir(dirfd).path, path);
5296
+ const joined2 = path.startsWith("/") ? path : `${this.dir(dirfd).path}/${path}`;
5297
+ return joined2.split("/").includes("..") ? physical(this.fs, joined2) : normalize(joined2);
5225
5298
  }
5226
5299
  open(path, oflags, rights, fdflags) {
5227
5300
  const device2 = deviceOf(path);
@@ -6892,9 +6965,9 @@ function procfsBridge(fs, tree) {
6892
6965
  }
6893
6966
  };
6894
6967
  const readOnly = (paths, run) => {
6895
- const physical = shadowing();
6968
+ const physical2 = shadowing();
6896
6969
  for (const [p, follow2] of paths) {
6897
- if (inProc(p) || physical && toProc(p, follow2) !== void 0) throw syncError("EROFS", p);
6970
+ if (inProc(p) || physical2 && toProc(p, follow2) !== void 0) throw syncError("EROFS", p);
6898
6971
  }
6899
6972
  return run();
6900
6973
  };