@ai-ecoverse/slicc-kernel 1.141.1 → 1.141.3

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.
@@ -1555,6 +1555,9 @@ function refusal(err) {
1555
1555
  const code2 = err?.code;
1556
1556
  return code2 === "EACCES" || code2 === "EPERM";
1557
1557
  }
1558
+ function gone(err) {
1559
+ return err?.code === "ENOENT";
1560
+ }
1558
1561
  function young(s) {
1559
1562
  return performance.now() - (s.filledAt ?? Number.NEGATIVE_INFINITY) < SHARED_TTL_MS;
1560
1563
  }
@@ -2072,7 +2075,9 @@ function createStreamOps(h) {
2072
2075
  if (s.handle === void 0) h.handled.delete(node);
2073
2076
  else h.handled.add(node);
2074
2077
  } catch (err) {
2075
- if (refusal(err)) throw new Fs.ErrnoError(wasiErrno(err.code));
2078
+ if (refusal(err) || gone(err)) {
2079
+ throw new Fs.ErrnoError(wasiErrno(err.code));
2080
+ }
2076
2081
  }
2077
2082
  };
2078
2083
  const permitted = (stream, created) => {
@@ -2778,7 +2783,7 @@ var KERNEL_VERSION, OS_RELEASE;
2778
2783
  var init_version = __esm({
2779
2784
  "src/version.ts"() {
2780
2785
  "use strict";
2781
- KERNEL_VERSION = true ? "1.141.1" : "0.0.0-dev";
2786
+ KERNEL_VERSION = true ? "1.141.3" : "0.0.0-dev";
2782
2787
  OS_RELEASE = "6.0.0-slicc";
2783
2788
  }
2784
2789
  });
@@ -5264,8 +5269,8 @@ var init_process_signals = __esm({
5264
5269
  const { caught, ignored, defaults = 0 } = masks;
5265
5270
  const nocldwait = masks.nocldwait === true;
5266
5271
  const was = this.reported;
5267
- const same = caught === was.caught && ignored === was.ignored && nocldwait === was.nocldwait;
5268
- if (same && defaults === 0) return;
5272
+ const same2 = caught === was.caught && ignored === was.ignored && nocldwait === was.nocldwait;
5273
+ if (same2 && defaults === 0) return;
5269
5274
  this.reported = { caught, ignored, nocldwait };
5270
5275
  const req = {
5271
5276
  op: "sig-mask",
@@ -5350,7 +5355,7 @@ function createSocketKernel(deps) {
5350
5355
  call2(req);
5351
5356
  return 0;
5352
5357
  };
5353
- const guard = (op) => {
5358
+ const guard2 = (op) => {
5354
5359
  for (; ; ) {
5355
5360
  try {
5356
5361
  return op();
@@ -5382,8 +5387,8 @@ function createSocketKernel(deps) {
5382
5387
  return stream.fd;
5383
5388
  };
5384
5389
  return {
5385
- socket: (domain, nonblock, cloexec) => guard(() => install(json2({ op: "sock-open", domain }), nonblock, cloexec)),
5386
- socketpair: (domain, nonblock, cloexec) => guard(() => {
5390
+ socket: (domain, nonblock, cloexec) => guard2(() => install(json2({ op: "sock-open", domain }), nonblock, cloexec)),
5391
+ socketpair: (domain, nonblock, cloexec) => guard2(() => {
5387
5392
  const [a, b] = json2({ op: "sock-pair", domain });
5388
5393
  let first;
5389
5394
  try {
@@ -5401,9 +5406,9 @@ function createSocketKernel(deps) {
5401
5406
  throw e;
5402
5407
  }
5403
5408
  }),
5404
- bind: (fd, given) => guard(() => done({ op: "sock-bind", fd: kfd(fd), addr: resolved(Fs, given) })),
5405
- listen: (fd, backlog) => guard(() => done({ op: "sock-listen", fd: kfd(fd), backlog })),
5406
- accept: (fd, nonblock, cloexec) => guard(() => {
5409
+ bind: (fd, given) => guard2(() => done({ op: "sock-bind", fd: kfd(fd), addr: resolved(Fs, given) })),
5410
+ listen: (fd, backlog) => guard2(() => done({ op: "sock-listen", fd: kfd(fd), backlog })),
5411
+ accept: (fd, nonblock, cloexec) => guard2(() => {
5407
5412
  const listener = socketAt(fd);
5408
5413
  const req = {
5409
5414
  op: "sock-accept",
@@ -5413,7 +5418,7 @@ function createSocketKernel(deps) {
5413
5418
  const got = json2(req);
5414
5419
  return { fd: install(got.fd, nonblock, cloexec), peer: got.peer };
5415
5420
  }),
5416
- connect: (fd, addr) => guard(() => {
5421
+ connect: (fd, addr) => guard2(() => {
5417
5422
  const stream = socketAt(fd);
5418
5423
  const nonblock = (stream.flags & O_NONBLOCK) !== 0;
5419
5424
  return done({
@@ -5423,12 +5428,12 @@ function createSocketKernel(deps) {
5423
5428
  nonblock
5424
5429
  });
5425
5430
  }),
5426
- shutdown: (fd, how) => guard(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
5427
- name: (fd, peer) => guard(() => json2({ op: "sock-name", fd: kfd(fd), peer })),
5428
- getopt: (fd, level, name2) => guard(() => ({ value: json2({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
5429
- setopt: (fd, level, name2, value2) => guard(() => done({ op: "sock-setopt", fd: kfd(fd), level, name: name2, value: value2 })),
5430
- resolve: (name2, family = 4) => guard(() => json2({ op: "sock-resolve", name: name2, family })),
5431
- send: (fd, bytes, flags) => guard(() => {
5431
+ shutdown: (fd, how) => guard2(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
5432
+ name: (fd, peer) => guard2(() => json2({ op: "sock-name", fd: kfd(fd), peer })),
5433
+ getopt: (fd, level, name2) => guard2(() => ({ value: json2({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
5434
+ setopt: (fd, level, name2, value2) => guard2(() => done({ op: "sock-setopt", fd: kfd(fd), level, name: name2, value: value2 })),
5435
+ resolve: (name2, family = 4) => guard2(() => json2({ op: "sock-resolve", name: name2, family })),
5436
+ send: (fd, bytes, flags) => guard2(() => {
5432
5437
  const stream = socketAt(fd);
5433
5438
  const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
5434
5439
  try {
@@ -5440,7 +5445,7 @@ function createSocketKernel(deps) {
5440
5445
  throw e;
5441
5446
  }
5442
5447
  }),
5443
- recv: (fd, max, flags) => guard(() => {
5448
+ recv: (fd, max, flags) => guard2(() => {
5444
5449
  const stream = socketAt(fd);
5445
5450
  const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
5446
5451
  return sys.read(stream.sliccKernelFd, max, { nonblock, peek: flags.peek === true });
@@ -5487,6 +5492,10 @@ function mayTrace(viewer, target) {
5487
5492
  const uid = of.ruid === by.euid && of.euid === by.euid && of.suid === by.euid;
5488
5493
  return uid && of.rgid === by.egid && of.egid === by.egid && of.sgid === by.egid;
5489
5494
  }
5495
+ function fileIdentity(ino, mtimeMs) {
5496
+ if (ino === void 0 || mtimeMs === void 0 || !Number.isFinite(mtimeMs)) return void 0;
5497
+ return `${ino}:${Math.trunc(mtimeMs)}`;
5498
+ }
5490
5499
  var init_proc_info = __esm({
5491
5500
  "src/kernel/proc-info.ts"() {
5492
5501
  "use strict";
@@ -5833,15 +5842,15 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
5833
5842
  readdir: (node) => listAll(node)
5834
5843
  };
5835
5844
  const track = (stream, names) => {
5836
- let current = names;
5845
+ let current2 = names;
5837
5846
  const remember2 = (list) => scans.set(stream, new Set(list.filter((n) => /^[1-9]\d*$/.test(n)).map(Number)));
5838
- remember2(current ?? []);
5847
+ remember2(current2 ?? []);
5839
5848
  Object.defineProperty(stream, "getdents", {
5840
5849
  configurable: true,
5841
5850
  enumerable: true,
5842
- get: () => current,
5851
+ get: () => current2,
5843
5852
  set: (next2) => {
5844
- current = next2;
5853
+ current2 = next2;
5845
5854
  if (next2) remember2(next2);
5846
5855
  }
5847
5856
  });
@@ -6972,7 +6981,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
6972
6981
  const live = (miss, path) => miss.until > now() && young2(miss) && (view === void 0 || miss.gen === void 0 || !view.changedSince(miss.gen, path).changed);
6973
6982
  const seen = new SeenAt(view, lstats);
6974
6983
  const kept = remember(cache, seen, blind, (entry2) => filled2.set(entry2));
6975
- const gone = (path) => goneAbove([lstats, stats], live, path);
6984
+ const gone2 = (path) => goneAbove([lstats, stats], live, path);
6976
6985
  const usable = (map, path) => {
6977
6986
  const hit = map.get(path);
6978
6987
  if (hit === void 0) return void 0;
@@ -6984,7 +6993,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
6984
6993
  cache.fresh();
6985
6994
  let hit = usable(map, path);
6986
6995
  if (hit === void 0) {
6987
- const missing2 = gone(path);
6996
+ const missing2 = gone2(path);
6988
6997
  if (missing2) throw missing2.error;
6989
6998
  hit = fetched({ view, now, seen, filled: filled2, cache }, map, path, get);
6990
6999
  }
@@ -7051,8 +7060,8 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
7051
7060
  readlink: (p) => {
7052
7061
  const known = blind ? void 0 : (cache.fresh(), lstats.get(p));
7053
7062
  const gen = seen.lstat(p);
7054
- const current = view !== void 0 && gen !== void 0 && !view.changedSince(gen, p).changed;
7055
- if (known && current && !("until" in known) && young2(known) && !known.isSymbolicLink) {
7063
+ const current2 = view !== void 0 && gen !== void 0 && !view.changedSince(gen, p).changed;
7064
+ if (known && current2 && !("until" in known) && young2(known) && !known.isSymbolicLink) {
7056
7065
  throw syncError("EINVAL", `'${p}' is not a symbolic link`);
7057
7066
  }
7058
7067
  return bridge.readlink(p);
@@ -7843,8 +7852,8 @@ var init_js_kernel = __esm({
7843
7852
  }
7844
7853
  async report(handlers, ignored, defaults) {
7845
7854
  const caught = caughtOf(handlers);
7846
- const same = caught === this.reported.caught && ignored === this.reported.ignored;
7847
- if (same && defaults === 0) return;
7855
+ const same2 = caught === this.reported.caught && ignored === this.reported.ignored;
7856
+ if (same2 && defaults === 0) return;
7848
7857
  this.reported = { caught, ignored };
7849
7858
  await this.call({ op: "sig-mask", caught, ignored, ...defaults ? { defaults } : {} });
7850
7859
  }
@@ -9318,6 +9327,10 @@ var init_wasi_fds = __esm({
9318
9327
  if (exclusive && this.isLink(path)) throw new WasiError("EEXIST");
9319
9328
  const s = this.statOrMissing(path);
9320
9329
  if (exclusive && s) throw new WasiError("EEXIST");
9330
+ if (s?.escape !== void 0) {
9331
+ refuseWrite({ readonly: true }, oflags, rights);
9332
+ return this.open(s.escape, oflags, rights, fdflags, mode);
9333
+ }
9321
9334
  if (oflags & OFLAGS.DIRECTORY && !s?.isDirectory) {
9322
9335
  throw new WasiError(s ? "ENOTDIR" : "ENOENT");
9323
9336
  }
@@ -11494,7 +11507,7 @@ var init_wasi_host = __esm({
11494
11507
  size: BigInt(size)
11495
11508
  };
11496
11509
  }
11497
- statOrphanable(path, size, orphan = false, gone = false) {
11510
+ statOrphanable(path, size, orphan = false, gone2 = false) {
11498
11511
  let s;
11499
11512
  if (!orphan) {
11500
11513
  try {
@@ -11503,7 +11516,7 @@ var init_wasi_host = __esm({
11503
11516
  }
11504
11517
  }
11505
11518
  const out = this.sized(path, s, size);
11506
- return gone ? { ...out, nlink: 0n } : out;
11519
+ return gone2 ? { ...out, nlink: 0n } : out;
11507
11520
  }
11508
11521
  synthetic(path) {
11509
11522
  return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH2 && !!this.o.kernel.sys.openClipboard;
@@ -11657,11 +11670,11 @@ var init_wasi_host = __esm({
11657
11670
  const asked = FSTFLAGS.ATIM | FSTFLAGS.ATIM_NOW | FSTFLAGS.MTIM | FSTFLAGS.MTIM_NOW;
11658
11671
  if (this.o.fs.owners && (flags & asked) === 0) return;
11659
11672
  const now = Date.now();
11660
- let current;
11673
+ let current2;
11661
11674
  const statOf = follow3 ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
11662
11675
  const kept = (field2) => {
11663
- current ??= statOf(path);
11664
- return current[field2] ?? current.mtimeMs ?? now;
11676
+ current2 ??= statOf(path);
11677
+ return current2[field2] ?? current2.mtimeMs ?? now;
11665
11678
  };
11666
11679
  const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS4) : kept(field2);
11667
11680
  (follow3 ? this.o.fs.utimes : this.o.fs.lutimes).call(
@@ -12407,10 +12420,40 @@ function directMiss(err, path) {
12407
12420
  if (err?.direct !== true) return false;
12408
12421
  return !path.split("/").some((part) => part === "." || part === "..");
12409
12422
  }
12410
- function routing(tree, toProc, shadowing) {
12423
+ function same(fs, path, id) {
12424
+ try {
12425
+ const st = fs.stat(path);
12426
+ const now = fileIdentity(st.ino, st.mtimeMs);
12427
+ return now === void 0 || now === id;
12428
+ } catch {
12429
+ return false;
12430
+ }
12431
+ }
12432
+ function current(fs, tree, q) {
12433
+ const to = tree.escapeTo(q);
12434
+ if (!to || to.id === void 0) return to?.target;
12435
+ if (!same(fs, to.target, to.id)) throw syncError("ENOENT", q);
12436
+ return to.target;
12437
+ }
12438
+ function guard(toProc, shadowing) {
12439
+ return (paths, run) => {
12440
+ const physical2 = shadowing();
12441
+ for (const [p, follow3] of paths) {
12442
+ if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
12443
+ }
12444
+ return run();
12445
+ };
12446
+ }
12447
+ function shownLink(fs, tree, q) {
12448
+ const target = tree.readlink(q);
12449
+ const to = tree.linkTo(q);
12450
+ if (!to) return target;
12451
+ return same(fs, to.target, to.id) ? target : `${target} (deleted)`;
12452
+ }
12453
+ function routing(fs, tree, toProc, shadowing) {
12411
12454
  return (p, inner, own, follow3 = true, outside) => {
12412
12455
  const proc = (q) => {
12413
- const target = outside ? tree.escape(q) : void 0;
12456
+ const target = outside ? current(fs, tree, q) : void 0;
12414
12457
  return target === void 0 ? inner(q) : outside(target);
12415
12458
  };
12416
12459
  if (inProc(p)) return proc(p);
@@ -12431,14 +12474,8 @@ function routing(tree, toProc, shadowing) {
12431
12474
  function procfsBridge(fs, tree) {
12432
12475
  const toProc = (path, follow3) => procPath(fs, path, follow3);
12433
12476
  const shadowing = physicalProc(fs);
12434
- const via = routing(tree, toProc, shadowing);
12435
- const readOnly2 = (paths, run) => {
12436
- const physical2 = shadowing();
12437
- for (const [p, follow3] of paths) {
12438
- if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
12439
- }
12440
- return run();
12441
- };
12477
+ const via = routing(fs, tree, toProc, shadowing);
12478
+ const readOnly2 = guard(toProc, shadowing);
12442
12479
  const snapshots = /* @__PURE__ */ new Map();
12443
12480
  let lastSnapshot = 0;
12444
12481
  const snapshot = (q) => {
@@ -12463,7 +12500,7 @@ function procfsBridge(fs, tree) {
12463
12500
  (q) => tree.stat(q),
12464
12501
  () => fs.stat(p),
12465
12502
  true,
12466
- (t) => fs.stat(t)
12503
+ (t) => ({ ...fs.stat(t), escape: t })
12467
12504
  ),
12468
12505
  lstat: (p) => via(
12469
12506
  p,
@@ -12502,7 +12539,7 @@ function procfsBridge(fs, tree) {
12502
12539
  },
12503
12540
  readlink: (p) => via(
12504
12541
  p,
12505
- (q) => tree.readlink(q),
12542
+ (q) => shownLink(fs, tree, q),
12506
12543
  () => fs.readlink(p),
12507
12544
  false
12508
12545
  ),
@@ -12542,7 +12579,7 @@ function procfsBridge(fs, tree) {
12542
12579
  return via(p, snapshot, () => fs.hold?.(p, held2, open, void 0, want, seen) ?? late(p));
12543
12580
  },
12544
12581
  kept: (handle) => snapshots.has(handle) || fs.kept?.(handle) === true,
12545
- escape: (p) => inProc(p) ? tree.escape(p) : void 0,
12582
+ escape: (p) => inProc(p) ? current(fs, tree, p) : void 0,
12546
12583
  pinned: (handle) => {
12547
12584
  const bytes = snapshots.get(handle);
12548
12585
  return bytes ? frozen(bytes) : fs.pinned?.(handle) ?? fs;
@@ -12642,12 +12679,7 @@ var init_wasi_procfs = __esm({
12642
12679
  const exe = () => this.info(Number(top))?.exe === void 0 ? [] : ["exe"];
12643
12680
  return { kind: "dir", names: () => [...PID_NAMES, ...exe(), "task"] };
12644
12681
  }
12645
- if (leaf === "exe") {
12646
- const info = this.info(Number(top));
12647
- if (info?.exe === void 0) return void 0;
12648
- const denied = !mayTrace(this.ownInfo(), info);
12649
- return { kind: "link", target: info.exe, ...denied ? { denied } : {} };
12650
- }
12682
+ if (leaf === "exe") return this.exe(Number(top));
12651
12683
  if (!PID_NAMES.includes(leaf)) return void 0;
12652
12684
  return {
12653
12685
  kind: "file",
@@ -12659,6 +12691,13 @@ var init_wasi_procfs = __esm({
12659
12691
  }
12660
12692
  };
12661
12693
  }
12694
+ exe(pid) {
12695
+ const info = this.info(pid);
12696
+ if (info?.exe === void 0) return void 0;
12697
+ const denied = !mayTrace(this.ownInfo(), info);
12698
+ const id = info.exeId === void 0 ? {} : { id: info.exeId };
12699
+ return { kind: "link", target: info.exe, ...denied ? { denied } : {}, ...id };
12700
+ }
12662
12701
  ownInfo() {
12663
12702
  const processes2 = this.listing().processes;
12664
12703
  return processes2.find((p) => p.tid === this.pid) ?? processes2.find((p) => p.pid === this.pid);
@@ -12724,10 +12763,18 @@ var init_wasi_procfs = __esm({
12724
12763
  return node.names();
12725
12764
  }
12726
12765
  escape(path) {
12766
+ return this.escapeTo(path)?.target;
12767
+ }
12768
+ escapeTo(path) {
12727
12769
  const node = this.node(this.parts(path, true));
12728
12770
  if (node?.kind !== "link" || !node.target.startsWith("/")) return void 0;
12729
12771
  if (node.denied) throw syncError("EACCES", path);
12730
- return node.target;
12772
+ return node.id === void 0 ? { target: node.target } : { target: node.target, id: node.id };
12773
+ }
12774
+ linkTo(path) {
12775
+ const node = this.node(this.parts(path, false));
12776
+ if (node?.kind !== "link" || node.id === void 0 || node.denied) return void 0;
12777
+ return { target: node.target, id: node.id };
12731
12778
  }
12732
12779
  readlink(path) {
12733
12780
  const node = this.find(path, false);
@@ -17052,9 +17099,9 @@ function ttyOps(kernel, syncKernel) {
17052
17099
  if (original) await setAttr(fd, original.termios);
17053
17100
  return;
17054
17101
  }
17055
- const current = await getAttr(fd);
17056
- if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
17057
- await setAttr(fd, rawOf(current));
17102
+ const current2 = await getAttr(fd);
17103
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current2 });
17104
+ await setAttr(fd, rawOf(current2));
17058
17105
  },
17059
17106
  async size(fd) {
17060
17107
  const [rows, columns] = await kernel.json({ op: "tty-winsz", fd });
@@ -17100,9 +17147,9 @@ function ttyOps(kernel, syncKernel) {
17100
17147
  if (original) syncSet(fd, original.termios);
17101
17148
  return;
17102
17149
  }
17103
- const current = syncGet(fd);
17104
- if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
17105
- syncSet(fd, rawOf(current));
17150
+ const current2 = syncGet(fd);
17151
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current2 });
17152
+ syncSet(fd, rawOf(current2));
17106
17153
  }
17107
17154
  };
17108
17155
  const modes = () => [...saved].reverse().map(([terminal, { fd, termios }]) => ({ terminal, fd, termios }));