@ai-ecoverse/slicc-kernel 1.141.1 → 1.141.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.
@@ -2778,7 +2778,7 @@ var KERNEL_VERSION, OS_RELEASE;
2778
2778
  var init_version = __esm({
2779
2779
  "src/version.ts"() {
2780
2780
  "use strict";
2781
- KERNEL_VERSION = true ? "1.141.1" : "0.0.0-dev";
2781
+ KERNEL_VERSION = true ? "1.141.2" : "0.0.0-dev";
2782
2782
  OS_RELEASE = "6.0.0-slicc";
2783
2783
  }
2784
2784
  });
@@ -5264,8 +5264,8 @@ var init_process_signals = __esm({
5264
5264
  const { caught, ignored, defaults = 0 } = masks;
5265
5265
  const nocldwait = masks.nocldwait === true;
5266
5266
  const was = this.reported;
5267
- const same = caught === was.caught && ignored === was.ignored && nocldwait === was.nocldwait;
5268
- if (same && defaults === 0) return;
5267
+ const same2 = caught === was.caught && ignored === was.ignored && nocldwait === was.nocldwait;
5268
+ if (same2 && defaults === 0) return;
5269
5269
  this.reported = { caught, ignored, nocldwait };
5270
5270
  const req = {
5271
5271
  op: "sig-mask",
@@ -5350,7 +5350,7 @@ function createSocketKernel(deps) {
5350
5350
  call2(req);
5351
5351
  return 0;
5352
5352
  };
5353
- const guard = (op) => {
5353
+ const guard2 = (op) => {
5354
5354
  for (; ; ) {
5355
5355
  try {
5356
5356
  return op();
@@ -5382,8 +5382,8 @@ function createSocketKernel(deps) {
5382
5382
  return stream.fd;
5383
5383
  };
5384
5384
  return {
5385
- socket: (domain, nonblock, cloexec) => guard(() => install(json2({ op: "sock-open", domain }), nonblock, cloexec)),
5386
- socketpair: (domain, nonblock, cloexec) => guard(() => {
5385
+ socket: (domain, nonblock, cloexec) => guard2(() => install(json2({ op: "sock-open", domain }), nonblock, cloexec)),
5386
+ socketpair: (domain, nonblock, cloexec) => guard2(() => {
5387
5387
  const [a, b] = json2({ op: "sock-pair", domain });
5388
5388
  let first;
5389
5389
  try {
@@ -5401,9 +5401,9 @@ function createSocketKernel(deps) {
5401
5401
  throw e;
5402
5402
  }
5403
5403
  }),
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(() => {
5404
+ bind: (fd, given) => guard2(() => done({ op: "sock-bind", fd: kfd(fd), addr: resolved(Fs, given) })),
5405
+ listen: (fd, backlog) => guard2(() => done({ op: "sock-listen", fd: kfd(fd), backlog })),
5406
+ accept: (fd, nonblock, cloexec) => guard2(() => {
5407
5407
  const listener = socketAt(fd);
5408
5408
  const req = {
5409
5409
  op: "sock-accept",
@@ -5413,7 +5413,7 @@ function createSocketKernel(deps) {
5413
5413
  const got = json2(req);
5414
5414
  return { fd: install(got.fd, nonblock, cloexec), peer: got.peer };
5415
5415
  }),
5416
- connect: (fd, addr) => guard(() => {
5416
+ connect: (fd, addr) => guard2(() => {
5417
5417
  const stream = socketAt(fd);
5418
5418
  const nonblock = (stream.flags & O_NONBLOCK) !== 0;
5419
5419
  return done({
@@ -5423,12 +5423,12 @@ function createSocketKernel(deps) {
5423
5423
  nonblock
5424
5424
  });
5425
5425
  }),
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(() => {
5426
+ shutdown: (fd, how) => guard2(() => done({ op: "sock-shutdown", fd: kfd(fd), how })),
5427
+ name: (fd, peer) => guard2(() => json2({ op: "sock-name", fd: kfd(fd), peer })),
5428
+ getopt: (fd, level, name2) => guard2(() => ({ value: json2({ op: "sock-getopt", fd: kfd(fd), level, name: name2 }) })),
5429
+ setopt: (fd, level, name2, value2) => guard2(() => done({ op: "sock-setopt", fd: kfd(fd), level, name: name2, value: value2 })),
5430
+ resolve: (name2, family = 4) => guard2(() => json2({ op: "sock-resolve", name: name2, family })),
5431
+ send: (fd, bytes, flags) => guard2(() => {
5432
5432
  const stream = socketAt(fd);
5433
5433
  const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
5434
5434
  try {
@@ -5440,7 +5440,7 @@ function createSocketKernel(deps) {
5440
5440
  throw e;
5441
5441
  }
5442
5442
  }),
5443
- recv: (fd, max, flags) => guard(() => {
5443
+ recv: (fd, max, flags) => guard2(() => {
5444
5444
  const stream = socketAt(fd);
5445
5445
  const nonblock = flags.dontwait === true || (stream.flags & O_NONBLOCK) !== 0;
5446
5446
  return sys.read(stream.sliccKernelFd, max, { nonblock, peek: flags.peek === true });
@@ -5487,6 +5487,10 @@ function mayTrace(viewer, target) {
5487
5487
  const uid = of.ruid === by.euid && of.euid === by.euid && of.suid === by.euid;
5488
5488
  return uid && of.rgid === by.egid && of.egid === by.egid && of.sgid === by.egid;
5489
5489
  }
5490
+ function fileIdentity(ino, mtimeMs) {
5491
+ if (ino === void 0 || mtimeMs === void 0 || !Number.isFinite(mtimeMs)) return void 0;
5492
+ return `${ino}:${Math.trunc(mtimeMs)}`;
5493
+ }
5490
5494
  var init_proc_info = __esm({
5491
5495
  "src/kernel/proc-info.ts"() {
5492
5496
  "use strict";
@@ -5833,15 +5837,15 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
5833
5837
  readdir: (node) => listAll(node)
5834
5838
  };
5835
5839
  const track = (stream, names) => {
5836
- let current = names;
5840
+ let current2 = names;
5837
5841
  const remember2 = (list) => scans.set(stream, new Set(list.filter((n) => /^[1-9]\d*$/.test(n)).map(Number)));
5838
- remember2(current ?? []);
5842
+ remember2(current2 ?? []);
5839
5843
  Object.defineProperty(stream, "getdents", {
5840
5844
  configurable: true,
5841
5845
  enumerable: true,
5842
- get: () => current,
5846
+ get: () => current2,
5843
5847
  set: (next2) => {
5844
- current = next2;
5848
+ current2 = next2;
5845
5849
  if (next2) remember2(next2);
5846
5850
  }
5847
5851
  });
@@ -7051,8 +7055,8 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
7051
7055
  readlink: (p) => {
7052
7056
  const known = blind ? void 0 : (cache.fresh(), lstats.get(p));
7053
7057
  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) {
7058
+ const current2 = view !== void 0 && gen !== void 0 && !view.changedSince(gen, p).changed;
7059
+ if (known && current2 && !("until" in known) && young2(known) && !known.isSymbolicLink) {
7056
7060
  throw syncError("EINVAL", `'${p}' is not a symbolic link`);
7057
7061
  }
7058
7062
  return bridge.readlink(p);
@@ -7843,8 +7847,8 @@ var init_js_kernel = __esm({
7843
7847
  }
7844
7848
  async report(handlers, ignored, defaults) {
7845
7849
  const caught = caughtOf(handlers);
7846
- const same = caught === this.reported.caught && ignored === this.reported.ignored;
7847
- if (same && defaults === 0) return;
7850
+ const same2 = caught === this.reported.caught && ignored === this.reported.ignored;
7851
+ if (same2 && defaults === 0) return;
7848
7852
  this.reported = { caught, ignored };
7849
7853
  await this.call({ op: "sig-mask", caught, ignored, ...defaults ? { defaults } : {} });
7850
7854
  }
@@ -9318,6 +9322,10 @@ var init_wasi_fds = __esm({
9318
9322
  if (exclusive && this.isLink(path)) throw new WasiError("EEXIST");
9319
9323
  const s = this.statOrMissing(path);
9320
9324
  if (exclusive && s) throw new WasiError("EEXIST");
9325
+ if (s?.escape !== void 0) {
9326
+ refuseWrite({ readonly: true }, oflags, rights);
9327
+ return this.open(s.escape, oflags, rights, fdflags, mode);
9328
+ }
9321
9329
  if (oflags & OFLAGS.DIRECTORY && !s?.isDirectory) {
9322
9330
  throw new WasiError(s ? "ENOTDIR" : "ENOENT");
9323
9331
  }
@@ -11657,11 +11665,11 @@ var init_wasi_host = __esm({
11657
11665
  const asked = FSTFLAGS.ATIM | FSTFLAGS.ATIM_NOW | FSTFLAGS.MTIM | FSTFLAGS.MTIM_NOW;
11658
11666
  if (this.o.fs.owners && (flags & asked) === 0) return;
11659
11667
  const now = Date.now();
11660
- let current;
11668
+ let current2;
11661
11669
  const statOf = follow3 ? this.o.fs.stat.bind(this.o.fs) : this.o.fs.lstat.bind(this.o.fs);
11662
11670
  const kept = (field2) => {
11663
- current ??= statOf(path);
11664
- return current[field2] ?? current.mtimeMs ?? now;
11671
+ current2 ??= statOf(path);
11672
+ return current2[field2] ?? current2.mtimeMs ?? now;
11665
11673
  };
11666
11674
  const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS4) : kept(field2);
11667
11675
  (follow3 ? this.o.fs.utimes : this.o.fs.lutimes).call(
@@ -12407,10 +12415,40 @@ function directMiss(err, path) {
12407
12415
  if (err?.direct !== true) return false;
12408
12416
  return !path.split("/").some((part) => part === "." || part === "..");
12409
12417
  }
12410
- function routing(tree, toProc, shadowing) {
12418
+ function same(fs, path, id) {
12419
+ try {
12420
+ const st = fs.stat(path);
12421
+ const now = fileIdentity(st.ino, st.mtimeMs);
12422
+ return now === void 0 || now === id;
12423
+ } catch {
12424
+ return false;
12425
+ }
12426
+ }
12427
+ function current(fs, tree, q) {
12428
+ const to = tree.escapeTo(q);
12429
+ if (!to || to.id === void 0) return to?.target;
12430
+ if (!same(fs, to.target, to.id)) throw syncError("ENOENT", q);
12431
+ return to.target;
12432
+ }
12433
+ function guard(toProc, shadowing) {
12434
+ return (paths, run) => {
12435
+ const physical2 = shadowing();
12436
+ for (const [p, follow3] of paths) {
12437
+ if (inProc(p) || physical2 && toProc(p, follow3) !== void 0) throw syncError("EROFS", p);
12438
+ }
12439
+ return run();
12440
+ };
12441
+ }
12442
+ function shownLink(fs, tree, q) {
12443
+ const target = tree.readlink(q);
12444
+ const to = tree.linkTo(q);
12445
+ if (!to) return target;
12446
+ return same(fs, to.target, to.id) ? target : `${target} (deleted)`;
12447
+ }
12448
+ function routing(fs, tree, toProc, shadowing) {
12411
12449
  return (p, inner, own, follow3 = true, outside) => {
12412
12450
  const proc = (q) => {
12413
- const target = outside ? tree.escape(q) : void 0;
12451
+ const target = outside ? current(fs, tree, q) : void 0;
12414
12452
  return target === void 0 ? inner(q) : outside(target);
12415
12453
  };
12416
12454
  if (inProc(p)) return proc(p);
@@ -12431,14 +12469,8 @@ function routing(tree, toProc, shadowing) {
12431
12469
  function procfsBridge(fs, tree) {
12432
12470
  const toProc = (path, follow3) => procPath(fs, path, follow3);
12433
12471
  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
- };
12472
+ const via = routing(fs, tree, toProc, shadowing);
12473
+ const readOnly2 = guard(toProc, shadowing);
12442
12474
  const snapshots = /* @__PURE__ */ new Map();
12443
12475
  let lastSnapshot = 0;
12444
12476
  const snapshot = (q) => {
@@ -12463,7 +12495,7 @@ function procfsBridge(fs, tree) {
12463
12495
  (q) => tree.stat(q),
12464
12496
  () => fs.stat(p),
12465
12497
  true,
12466
- (t) => fs.stat(t)
12498
+ (t) => ({ ...fs.stat(t), escape: t })
12467
12499
  ),
12468
12500
  lstat: (p) => via(
12469
12501
  p,
@@ -12502,7 +12534,7 @@ function procfsBridge(fs, tree) {
12502
12534
  },
12503
12535
  readlink: (p) => via(
12504
12536
  p,
12505
- (q) => tree.readlink(q),
12537
+ (q) => shownLink(fs, tree, q),
12506
12538
  () => fs.readlink(p),
12507
12539
  false
12508
12540
  ),
@@ -12542,7 +12574,7 @@ function procfsBridge(fs, tree) {
12542
12574
  return via(p, snapshot, () => fs.hold?.(p, held2, open, void 0, want, seen) ?? late(p));
12543
12575
  },
12544
12576
  kept: (handle) => snapshots.has(handle) || fs.kept?.(handle) === true,
12545
- escape: (p) => inProc(p) ? tree.escape(p) : void 0,
12577
+ escape: (p) => inProc(p) ? current(fs, tree, p) : void 0,
12546
12578
  pinned: (handle) => {
12547
12579
  const bytes = snapshots.get(handle);
12548
12580
  return bytes ? frozen(bytes) : fs.pinned?.(handle) ?? fs;
@@ -12642,12 +12674,7 @@ var init_wasi_procfs = __esm({
12642
12674
  const exe = () => this.info(Number(top))?.exe === void 0 ? [] : ["exe"];
12643
12675
  return { kind: "dir", names: () => [...PID_NAMES, ...exe(), "task"] };
12644
12676
  }
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
- }
12677
+ if (leaf === "exe") return this.exe(Number(top));
12651
12678
  if (!PID_NAMES.includes(leaf)) return void 0;
12652
12679
  return {
12653
12680
  kind: "file",
@@ -12659,6 +12686,13 @@ var init_wasi_procfs = __esm({
12659
12686
  }
12660
12687
  };
12661
12688
  }
12689
+ exe(pid) {
12690
+ const info = this.info(pid);
12691
+ if (info?.exe === void 0) return void 0;
12692
+ const denied = !mayTrace(this.ownInfo(), info);
12693
+ const id = info.exeId === void 0 ? {} : { id: info.exeId };
12694
+ return { kind: "link", target: info.exe, ...denied ? { denied } : {}, ...id };
12695
+ }
12662
12696
  ownInfo() {
12663
12697
  const processes2 = this.listing().processes;
12664
12698
  return processes2.find((p) => p.tid === this.pid) ?? processes2.find((p) => p.pid === this.pid);
@@ -12724,10 +12758,18 @@ var init_wasi_procfs = __esm({
12724
12758
  return node.names();
12725
12759
  }
12726
12760
  escape(path) {
12761
+ return this.escapeTo(path)?.target;
12762
+ }
12763
+ escapeTo(path) {
12727
12764
  const node = this.node(this.parts(path, true));
12728
12765
  if (node?.kind !== "link" || !node.target.startsWith("/")) return void 0;
12729
12766
  if (node.denied) throw syncError("EACCES", path);
12730
- return node.target;
12767
+ return node.id === void 0 ? { target: node.target } : { target: node.target, id: node.id };
12768
+ }
12769
+ linkTo(path) {
12770
+ const node = this.node(this.parts(path, false));
12771
+ if (node?.kind !== "link" || node.id === void 0 || node.denied) return void 0;
12772
+ return { target: node.target, id: node.id };
12731
12773
  }
12732
12774
  readlink(path) {
12733
12775
  const node = this.find(path, false);
@@ -17052,9 +17094,9 @@ function ttyOps(kernel, syncKernel) {
17052
17094
  if (original) await setAttr(fd, original.termios);
17053
17095
  return;
17054
17096
  }
17055
- const current = await getAttr(fd);
17056
- if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
17057
- await setAttr(fd, rawOf(current));
17097
+ const current2 = await getAttr(fd);
17098
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current2 });
17099
+ await setAttr(fd, rawOf(current2));
17058
17100
  },
17059
17101
  async size(fd) {
17060
17102
  const [rows, columns] = await kernel.json({ op: "tty-winsz", fd });
@@ -17100,9 +17142,9 @@ function ttyOps(kernel, syncKernel) {
17100
17142
  if (original) syncSet(fd, original.termios);
17101
17143
  return;
17102
17144
  }
17103
- const current = syncGet(fd);
17104
- if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
17105
- syncSet(fd, rawOf(current));
17145
+ const current2 = syncGet(fd);
17146
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current2 });
17147
+ syncSet(fd, rawOf(current2));
17106
17148
  }
17107
17149
  };
17108
17150
  const modes = () => [...saved].reverse().map(([terminal, { fd, termios }]) => ({ terminal, fd, termios }));