@ai-ecoverse/slicc-kernel 1.29.0 → 1.29.2

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.
@@ -694,6 +694,22 @@ function createHelpers(Fs, ops) {
694
694
  function createNodeOps(h) {
695
695
  const { Fs, bridgeOf, call: call2, metadataCall, makeNode, statOf, childPath, flushNode, truncate } = h;
696
696
  const { ensureLoaded } = h;
697
+ const setTimes = (node, path, atime, mtime) => {
698
+ if (Fs.isLink(node.mode)) {
699
+ metadataCall(() => bridgeOf(node).lutimes(path, atime, mtime));
700
+ return;
701
+ }
702
+ flushNode(node);
703
+ metadataCall(() => bridgeOf(node).utimes(path, atime, mtime));
704
+ };
705
+ const timesOf = (node, attr2) => {
706
+ const mtime = toMs(attr2.mtime) ?? attr2.timestamp;
707
+ const atime = toMs(attr2.atime);
708
+ if (mtime !== void 0 && attr2.atime !== null) return [atime ?? mtime, mtime];
709
+ if (atime === void 0 && mtime === void 0) return void 0;
710
+ const st = statOf(node);
711
+ return [atime ?? st.atimeMs ?? st.mtimeMs ?? 0, mtime ?? st.mtimeMs ?? 0];
712
+ };
697
713
  return {
698
714
  getattr(node) {
699
715
  const st = statOf(node);
@@ -735,12 +751,8 @@ function createNodeOps(h) {
735
751
  if (attr2.size !== void 0 && attr2.size !== null && Fs.isFile(node.mode)) {
736
752
  truncate(node, attr2.size);
737
753
  }
738
- const mtime = toMs(attr2.mtime) ?? attr2.timestamp;
739
- if (mtime !== void 0) {
740
- const atime = toMs(attr2.atime) ?? mtime;
741
- flushNode(node);
742
- metadataCall(() => bridgeOf(node).utimes(path, atime, mtime));
743
- }
754
+ const times = timesOf(node, attr2);
755
+ if (times) setTimes(node, path, ...times);
744
756
  node.live.stat = void 0;
745
757
  },
746
758
  lookup(parent, name) {
@@ -1451,6 +1463,9 @@ function createSyncFsSabBridge(transport, opts = {}) {
1451
1463
  utimes: (path, atimeMs, mtimeMs) => {
1452
1464
  run({ op: "utimes", path, atimeMs, mtimeMs }, path);
1453
1465
  },
1466
+ lutimes: (path, atimeMs, mtimeMs) => {
1467
+ run({ op: "lutimes", path, atimeMs, mtimeMs }, path);
1468
+ },
1454
1469
  hold: (path, held) => {
1455
1470
  run({ op: "hold", path, mode: held ? 1 : 0 }, path);
1456
1471
  },
@@ -2267,6 +2282,32 @@ function wrapCloexecSyscalls(imports, glue, deps) {
2267
2282
  }
2268
2283
  }
2269
2284
  }
2285
+ function noFollowUtimes(imports, fs, glue) {
2286
+ for (const namespace of namespaces(imports)) {
2287
+ const key = Object.keys(namespace).find(
2288
+ (name) => glue !== void 0 && namespace[name] === glue || name === "__syscall_utimensat"
2289
+ );
2290
+ const utimensat = key === void 0 ? void 0 : namespace[key];
2291
+ if (key === void 0 || typeof utimensat !== "function") continue;
2292
+ namespace[key] = (dirfd, path, times, flags) => {
2293
+ const Fs = fs();
2294
+ const { utime, lookupPath, ErrnoError } = Fs ?? {};
2295
+ if (!Fs || !(flags & AT_SYMLINK_NOFOLLOW) || !utime || !lookupPath || !ErrnoError) {
2296
+ return utimensat(dirfd, path, times, flags);
2297
+ }
2298
+ Fs.utime = (at, atime, mtime) => {
2299
+ const { node } = lookupPath.call(Fs, at, { follow: false });
2300
+ if (!node.node_ops.setattr) throw new ErrnoError(EMSCRIPTEN_EPERM);
2301
+ node.node_ops.setattr(node, { atime, mtime });
2302
+ };
2303
+ try {
2304
+ return utimensat(dirfd, path, times, flags);
2305
+ } finally {
2306
+ Fs.utime = utime;
2307
+ }
2308
+ };
2309
+ }
2310
+ }
2270
2311
  function errnoOf(err) {
2271
2312
  const { errno: errno2, code: code2 } = err ?? {};
2272
2313
  if (typeof errno2 === "number") return errno2;
@@ -2515,7 +2556,7 @@ function useMounts(Fs, env = {}, live = false) {
2515
2556
  }
2516
2557
  };
2517
2558
  }
2518
- var O_CLOEXEC, FD_CLOEXEC, F_DUPFD, F_GETFD, F_SETFD, F_GETFL, F_DUPFD_CLOEXEC, tracked, IMPORT_NAMES, EBADF, DIR_MODE, LINK_MODE, O_ACCMODE, O_CREAT2, field, NAME;
2559
+ 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, DIR_MODE, LINK_MODE, O_ACCMODE, O_CREAT2, field, NAME;
2519
2560
  var init_process_fds = __esm({
2520
2561
  "src/process/process-fds.ts"() {
2521
2562
  "use strict";
@@ -2540,6 +2581,8 @@ var init_process_fds = __esm({
2540
2581
  setitimer: "_setitimer_js"
2541
2582
  };
2542
2583
  EBADF = 8;
2584
+ AT_SYMLINK_NOFOLLOW = 256;
2585
+ EMSCRIPTEN_EPERM = 63;
2543
2586
  DIR_MODE = 16749;
2544
2587
  LINK_MODE = 41408;
2545
2588
  O_ACCMODE = 3;
@@ -3476,6 +3519,15 @@ function ownValue(module, name) {
3476
3519
  const own = Object.getOwnPropertyDescriptor(module, name);
3477
3520
  return own && "value" in own ? own.value : void 0;
3478
3521
  }
3522
+ function identify(transport, init) {
3523
+ const r = transport.call({ op: "proc-identity" }, Number.POSITIVE_INFINITY, "proc-identity");
3524
+ const id = r.ok && r.kind === "json" ? r.json : null;
3525
+ return id ?? { pid: init.pid, ppid: init.ppid ?? 1 };
3526
+ }
3527
+ function liveParent(imports, parent) {
3528
+ const env = imports.env;
3529
+ if (env && typeof env.slicc_getppid_js === "function") env.slicc_getppid_js = parent;
3530
+ }
3479
3531
  function signalMasks(m) {
3480
3532
  const mask = m.sliccSigMask;
3481
3533
  const caught = mask?.(0) ?? -1;
@@ -3519,11 +3571,12 @@ async function runWasmProcess(init, port, deps = {}) {
3519
3571
  ready = resolve;
3520
3572
  failed2 = reject;
3521
3573
  });
3574
+ const id = identify(transport, init);
3522
3575
  const module = {
3523
3576
  noInitialRun: true,
3524
3577
  thisProgram: init.argv0,
3525
- sliccPid: init.pid,
3526
- ...init.ppid !== void 0 ? { sliccPpid: init.ppid } : {},
3578
+ sliccPid: id.pid,
3579
+ sliccPpid: id.ppid,
3527
3580
  sliccEnv: init.env,
3528
3581
  print: say(1),
3529
3582
  printErr: say(2),
@@ -3543,6 +3596,12 @@ async function runWasmProcess(init, port, deps = {}) {
3543
3596
  }
3544
3597
  }
3545
3598
  });
3599
+ liveParent(imports, () => identify(transport, init).ppid);
3600
+ noFollowUtimes(
3601
+ imports,
3602
+ () => ownValue(module, "FS"),
3603
+ ownValue(module, "sliccSyscalls")?.utimensat
3604
+ );
3546
3605
  const glue = ownValue(module, "sliccFdImports");
3547
3606
  syncFsync(imports, () => ownValue(module, "FS"), glue);
3548
3607
  positionalIo(imports, {
@@ -3891,6 +3950,7 @@ function cachingBridge(bridge, now = () => performance.now()) {
3891
3950
  symlink: (target, link) => mutating(() => bridge.symlink(target, link)),
3892
3951
  chmod: (p, mode) => mutating(() => bridge.chmod(p, mode)),
3893
3952
  utimes: (p, a, m) => mutating(() => bridge.utimes(p, a, m)),
3953
+ lutimes: (p, a, m) => mutating(() => bridge.lutimes(p, a, m)),
3894
3954
  ...bridge.pread && bridge.pwrite && bridge.truncate ? {
3895
3955
  pread: bridge.pread.bind(bridge),
3896
3956
  pwrite: (p, at, bytes, transfer) => mutating(() => bridge.pwrite?.(p, at, bytes, transfer)),
@@ -5023,10 +5083,10 @@ var init_wasi_host = __esm({
5023
5083
  return {
5024
5084
  path_open: (dirfd, _lookup, p, l, oflags, rights, _inheriting, fdflags, out) => void mem.view().setUint32(out, fds.open(at(dirfd, p, l), oflags, rights, fdflags), true),
5025
5085
  path_filestat_get: (dirfd, lookup, p, l, out) => void this.writeFilestat(out, this.pathFilestat(at(dirfd, p, l), lookup)),
5026
- path_filestat_set_times: (dirfd, _lookup, p, l, atim, mtim, flags) => {
5086
+ path_filestat_set_times: (dirfd, lookup, p, l, atim, mtim, flags) => {
5027
5087
  const path = at(dirfd, p, l);
5028
5088
  fds.flushPath(path);
5029
- this.setTimes(path, atim, mtim, flags);
5089
+ this.setTimes(path, atim, mtim, flags, (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0);
5030
5090
  },
5031
5091
  path_create_directory: (dirfd, p, l) => {
5032
5092
  const path = at(dirfd, p, l);
@@ -5259,15 +5319,20 @@ var init_wasi_host = __esm({
5259
5319
  const follow = (lookup & LOOKUP_SYMLINK_FOLLOW) !== 0;
5260
5320
  return filestatOf(path, follow ? this.o.fs.stat(path) : this.o.fs.lstat(path));
5261
5321
  }
5262
- setTimes(path, atim, mtim, flags) {
5322
+ setTimes(path, atim, mtim, flags, follow = true) {
5263
5323
  const now = Date.now();
5264
5324
  let current;
5265
- const kept = () => current ??= this.o.fs.stat(path).mtimeMs ?? now;
5266
- const pick = (set, setNow, value2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS) : kept();
5267
- this.o.fs.utimes(
5325
+ const statOf = follow ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
5326
+ const kept = (field2) => {
5327
+ current ??= statOf(path);
5328
+ return current[field2] ?? current.mtimeMs ?? now;
5329
+ };
5330
+ const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS) : kept(field2);
5331
+ (follow ? this.o.fs.utimes : this.o.fs.lutimes).call(
5332
+ this.o.fs,
5268
5333
  path,
5269
- pick(FSTFLAGS.ATIM, FSTFLAGS.ATIM_NOW, atim),
5270
- pick(FSTFLAGS.MTIM, FSTFLAGS.MTIM_NOW, mtim)
5334
+ pick(FSTFLAGS.ATIM, FSTFLAGS.ATIM_NOW, atim, "atimeMs"),
5335
+ pick(FSTFLAGS.MTIM, FSTFLAGS.MTIM_NOW, mtim, "mtimeMs")
5271
5336
  );
5272
5337
  }
5273
5338
  readdir(fd, buf, len, cookie, usedPtr) {
@@ -6750,7 +6815,7 @@ var init_wasix_host = __esm({
6750
6815
  proc_id: (out) => void mem.view().setUint32(out, host.o.pid, true),
6751
6816
  proc_parent: (pid, out) => {
6752
6817
  if (pid !== 0 && pid !== host.o.pid) throw new WasiError("ESRCH");
6753
- mem.view().setUint32(out, host.o.ppid ?? 1, true);
6818
+ mem.view().setUint32(out, host.o.parent?.() ?? host.o.ppid ?? 1, true);
6754
6819
  },
6755
6820
  getcwd: (buf, lenPtr) => {
6756
6821
  const bytes = new TextEncoder().encode(host.cwd);
@@ -7286,6 +7351,7 @@ async function runWasiProcess(init, port) {
7286
7351
  });
7287
7352
  const main = {};
7288
7353
  const { transport, sys, call: kernelCall, say } = kernelOf(init, port, signals, sizeOf(main));
7354
+ const id = identify(transport, init);
7289
7355
  const stats = init.env.SLICC_WASI_STATS === "1" ? new WasiStats() : void 0;
7290
7356
  const call2 = stats ? timedCalls(stats, kernelCall) : kernelCall;
7291
7357
  const { module } = init.program;
@@ -7306,8 +7372,9 @@ async function runWasiProcess(init, port) {
7306
7372
  args: [init.argv0, ...init.args],
7307
7373
  env: init.env,
7308
7374
  cwd: fork?.cwd ?? init.cwd,
7309
- pid: init.pid,
7310
- ...init.ppid !== void 0 ? { ppid: init.ppid } : {},
7375
+ pid: id.pid,
7376
+ ppid: id.ppid,
7377
+ parent: () => identify(transport, init).ppid,
7311
7378
  kernel: { sys: traced(stats, "kernel", sys), call: call2 },
7312
7379
  fs: cachingBridge(traced(stats, "fs", createSyncFsSabBridge(transport))),
7313
7380
  ...fork?.shared && threads ? { shared: threads.ids } : fork ? { forked: { fds: fork.fds, cloexec: fork.cloexec } } : { inherited: init.fds }
@@ -7381,12 +7448,14 @@ async function runWasiThread(init, port) {
7381
7448
  const { thread } = init;
7382
7449
  const threads = new WasiThreads(port, thread.memory, threadCap(init.env), thread.tid, thread.ids);
7383
7450
  threads.received = thread.modules;
7451
+ const id = identify(transport, init);
7384
7452
  const host = new WasiHost({
7385
7453
  args: [init.argv0, ...init.args],
7386
7454
  env: init.env,
7387
7455
  cwd: init.cwd,
7388
- pid: init.pid,
7389
- ...init.ppid !== void 0 ? { ppid: init.ppid } : {},
7456
+ pid: id.pid,
7457
+ ppid: id.ppid,
7458
+ parent: () => identify(transport, init).ppid,
7390
7459
  kernel: { sys, call: call2 },
7391
7460
  fs: cachingBridge(createSyncFsSabBridge(transport)),
7392
7461
  shared: threads.ids