@ai-ecoverse/slicc-kernel 1.112.0 → 1.114.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.
package/dist/node.js CHANGED
@@ -2129,6 +2129,14 @@ var SIGNAL_BY_NAME = {
2129
2129
  SIGSTOP: SIG.STOP,
2130
2130
  SIGCONT: SIG.CONT
2131
2131
  };
2132
+ var SI = { USER: 0, QUEUE: -1, TIMER: -2, TKILL: -6, KERNEL: 128 };
2133
+ var CLD = { EXITED: 1, KILLED: 2, DUMPED: 3, STOPPED: 5, CONTINUED: 6 };
2134
+ var KERNEL_SIGINFO = Object.freeze({
2135
+ code: SI.KERNEL,
2136
+ pid: 0,
2137
+ uid: 0,
2138
+ status: 0
2139
+ });
2132
2140
 
2133
2141
  // src/body-idle.ts
2134
2142
  var BODY_IDLE_MS = 5 * 60 * 1e3;
@@ -4099,6 +4107,8 @@ var S_ISGID3 = 1024;
4099
4107
  var READ_ATTEMPTS = 3;
4100
4108
  var MAX_LINKS5 = 40;
4101
4109
  var CHECK_MS = 1e3;
4110
+ var ABSENT_MS = 2;
4111
+ var ABSENT_NAMES = 4096;
4102
4112
  var FILE_HANDLES = 4096;
4103
4113
  var STALE = /* @__PURE__ */ new Set(["NotFoundError", "TypeMismatchError"]);
4104
4114
  var EXECUTABLE = /\/node_modules\/(?:@[^/]+\/)?[^/]+\/bin\//;
@@ -4229,6 +4239,8 @@ var OpfsFs = class {
4229
4239
  meta;
4230
4240
  dirs = new PathMap();
4231
4241
  files = new PathMap();
4242
+ absent = new PathMap();
4243
+ changes = 0;
4232
4244
  snapshots = /* @__PURE__ */ new WeakMap();
4233
4245
  found = /* @__PURE__ */ new WeakMap();
4234
4246
  checked = /* @__PURE__ */ new WeakMap();
@@ -4467,8 +4479,14 @@ var OpfsFs = class {
4467
4479
  return true;
4468
4480
  }
4469
4481
  forget(path) {
4482
+ this.changes++;
4470
4483
  this.dirs.deleteTree(path);
4471
4484
  this.files.deleteTree(path);
4485
+ this.absent.deleteTree(path);
4486
+ }
4487
+ missed(path) {
4488
+ if (this.absent.size >= ABSENT_NAMES) this.absent.clear();
4489
+ this.absent.set(path, performance.now());
4472
4490
  }
4473
4491
  remember(path, handle, looked = false) {
4474
4492
  if (handle.kind !== "file") return handle;
@@ -4518,8 +4536,15 @@ var OpfsFs = class {
4518
4536
  this.snapshots.delete(cached);
4519
4537
  }
4520
4538
  }
4539
+ const kept = this.dirs.get(path);
4540
+ if (kept && await this.current(path, kept)) return kept;
4541
+ const gone = this.absent.get(path);
4542
+ if (gone !== void 0 && performance.now() - gone < ABSENT_MS) {
4543
+ throw translate({ name: "NotFoundError" }, path);
4544
+ }
4545
+ const seen = this.changes;
4521
4546
  const [dir, name2] = await this.parent(path);
4522
- const known = this.dirs.has(path);
4547
+ const known = kept !== void 0;
4523
4548
  return this.inDir(dir, async (parent) => {
4524
4549
  const [first, second] = known ? ["directory", "file"] : ["file", "directory"];
4525
4550
  try {
@@ -4529,7 +4554,9 @@ var OpfsFs = class {
4529
4554
  }
4530
4555
  return this.remember(path, await this.child(parent, name2, second), true);
4531
4556
  }).catch((err) => {
4532
- throw translate(err, path);
4557
+ const error = translate(err, path);
4558
+ if (error.code === "ENOENT" && seen === this.changes) this.missed(path);
4559
+ throw error;
4533
4560
  });
4534
4561
  }
4535
4562
  real(path) {
@@ -4656,7 +4683,9 @@ var OpfsFs = class {
4656
4683
  }
4657
4684
  flushing = {};
4658
4685
  touch(now, ...dirs) {
4686
+ this.changes++;
4659
4687
  for (const dir of dirs) {
4688
+ this.absent.deleteTree(dir);
4660
4689
  this.dirTimes.set(dir, now);
4661
4690
  this.dirDirty.add(dir);
4662
4691
  }
@@ -6510,7 +6539,7 @@ function satisfies(version, range2) {
6510
6539
  }
6511
6540
 
6512
6541
  // src/version.ts
6513
- var KERNEL_VERSION = true ? "1.112.0" : "0.0.0-dev";
6542
+ var KERNEL_VERSION = true ? "1.114.0" : "0.0.0-dev";
6514
6543
  var OS_RELEASE = "6.0.0-slicc";
6515
6544
  function procVersion() {
6516
6545
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9164,8 +9193,16 @@ var ChildTable = class {
9164
9193
  void handle.exited.then((code) => {
9165
9194
  child.code = code;
9166
9195
  this.watchers.delete(handle.pid);
9196
+ const termsig = handle.termsig?.();
9167
9197
  if (!this.kept.delete(handle.pid) && this.autoReap?.()) this.reap(handle.pid, code);
9168
- this.onChildState?.();
9198
+ const uid = handle.uid?.();
9199
+ this.onChildState?.({
9200
+ pid: handle.pid,
9201
+ state: "exited",
9202
+ status: termsig ?? code,
9203
+ termsig,
9204
+ uid
9205
+ });
9169
9206
  });
9170
9207
  handle.onState?.((state, sig) => {
9171
9208
  child.stopReport = state === "stopped" ? sig : void 0;
@@ -9175,7 +9212,7 @@ var ChildTable = class {
9175
9212
  const waiters = this.stateChanged;
9176
9213
  this.stateChanged = [];
9177
9214
  for (const wake of waiters) wake();
9178
- this.onChildState?.();
9215
+ this.onChildState?.({ pid: handle.pid, state, status: sig, uid: handle.uid?.() });
9179
9216
  });
9180
9217
  this.children.set(handle.pid, child);
9181
9218
  return handle.pid;
@@ -17087,6 +17124,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
17087
17124
  "sig-mask",
17088
17125
  "sig-inherited",
17089
17126
  "sig-waiting",
17127
+ "sig-info",
17090
17128
  "sig-pause",
17091
17129
  ...SOCKET_OPS,
17092
17130
  ...EPOLL_OPS,
@@ -17168,7 +17206,7 @@ var WasmProcess = class {
17168
17206
  this.children = new ChildTable(fds, options.spawner, options.forker);
17169
17207
  this.nodes = options.nodes ?? new VfsNodes(options.fs);
17170
17208
  if (!options.nodes) options.openFiles?.add(this.nodes);
17171
- this.children.onChildState = () => this.signal(SIG.CHLD);
17209
+ this.children.onChildState = (child) => this.signal(SIG.CHLD, child && this.childInfo(child));
17172
17210
  this.children.autoReap = () => this.reapsChildren();
17173
17211
  this.seedDl(options.dl);
17174
17212
  this.children.onReap = (pid2) => {
@@ -17185,10 +17223,43 @@ var WasmProcess = class {
17185
17223
  inheritable(fork = false) {
17186
17224
  return ((fork ? 0 : this.ignored) | this.inherited) & ~this.caught;
17187
17225
  }
17188
- signal(sig) {
17226
+ sigInfos = /* @__PURE__ */ new Map();
17227
+ signal(sig, info) {
17228
+ const pending = ((this.options.pendingBits?.() ?? 0) & sigbit(sig)) !== 0;
17229
+ const outcome = this.signalOutcome(sig, info);
17230
+ if (outcome === "deliver" && !(pending && this.sigInfos.has(`0:${sig}`))) {
17231
+ this.sigInfos.set(`0:${sig}`, info ?? KERNEL_SIGINFO);
17232
+ }
17233
+ return outcome;
17234
+ }
17235
+ async threadKill(tid, sig) {
17236
+ const info = await this.threadSender(sig);
17237
+ if (this.options.threadKill?.(tid, sig)) this.sigInfos.set(`${tid}:${sig}`, info);
17238
+ else this.options.raise?.(sig, info);
17239
+ }
17240
+ async threadSender(sig) {
17241
+ const pid = (await this.options.identity?.())?.pid ?? this.pid;
17242
+ const code = sig === SIG.PIPE ? SI.USER : SI.TKILL;
17243
+ return { code, pid, uid: this.cred.ruid, status: 0 };
17244
+ }
17245
+ childInfo(child) {
17246
+ const code = child.state === "stopped" ? CLD.STOPPED : child.state === "continued" ? CLD.CONTINUED : child.termsig ? CLD.KILLED : CLD.EXITED;
17247
+ return { code, pid: child.pid, uid: child.uid ?? this.cred.ruid, status: child.status };
17248
+ }
17249
+ takeSigInfo(sig, tid) {
17250
+ for (const key of [`${tid}:${sig}`, `0:${sig}`]) {
17251
+ const info = this.sigInfos.get(key);
17252
+ if (info) {
17253
+ this.sigInfos.delete(key);
17254
+ return info;
17255
+ }
17256
+ }
17257
+ return null;
17258
+ }
17259
+ signalOutcome(sig, info) {
17189
17260
  if (this.execChild !== void 0) {
17190
17261
  if (sig === SIG.CONT) this.cont();
17191
- void Promise.resolve(this.options.kill?.(this.execChild, sig)).catch(() => void 0);
17262
+ void Promise.resolve(this.options.kill?.(this.execChild, sig, info)).catch(() => void 0);
17192
17263
  if (sig !== SIG.KILL) return "forward";
17193
17264
  if (!this.options.writesBack?.(this.execChild)) return "terminate";
17194
17265
  this.wake?.();
@@ -18249,8 +18320,10 @@ var WasmProcess = class {
18249
18320
  case "sig-pause":
18250
18321
  return this.pause(cancelled);
18251
18322
  case "thread-kill":
18252
- if (!this.options.threadKill?.(req.tid, req.sig)) this.options.raise?.(req.sig);
18323
+ await this.threadKill(req.tid, req.sig);
18253
18324
  return { ok: true, kind: "void" };
18325
+ case "sig-info":
18326
+ return { ok: true, kind: "json", json: this.takeSigInfo(req.sig, req.tid ?? 0) };
18254
18327
  case "proc-captured":
18255
18328
  return { ok: true, kind: "bytes", bytes: this.children.captured(req.pid, req.slot) };
18256
18329
  case "proc-sudo":
@@ -18729,7 +18802,7 @@ function spawnWasmProcess(opts) {
18729
18802
  opts,
18730
18803
  header4,
18731
18804
  {
18732
- raise: (sig) => signal(sig),
18805
+ raise: (sig, info) => signal(sig, info),
18733
18806
  threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig),
18734
18807
  unblockedThread: (sig) => unblockedThread(threadSignals, sig),
18735
18808
  ...opts.program.abi === "js" ? {
@@ -18851,8 +18924,9 @@ function spawnWasmProcess(opts) {
18851
18924
  if (opts.program.abi !== "wasi" || done4) finish(code, sig);
18852
18925
  else dying.start(code, sig, header4, process2, () => finish(code, sig));
18853
18926
  };
18854
- const signal = (sig) => {
18855
- if (process2.signal(sig) === "terminate") terminate(sig === SIG.KILL ? 137 : 128 + sig, sig);
18927
+ const signal = (sig, info) => {
18928
+ if (process2.signal(sig, info) === "terminate")
18929
+ terminate(sig === SIG.KILL ? 137 : 128 + sig, sig);
18856
18930
  };
18857
18931
  const kill = (code = 137) => finish(code, code > 128 && code < 160 ? code - 128 : void 0);
18858
18932
  return {
@@ -19022,14 +19096,14 @@ var JobTable = class {
19022
19096
  this.foreground.set(tty, member.pgid);
19023
19097
  return true;
19024
19098
  }
19025
- killGroup(pgid, sig, may = () => true) {
19099
+ killGroup(pgid, sig, may = () => true, info) {
19026
19100
  const group = [...this.members.values()].filter((m) => m.pgid === pgid);
19027
19101
  const targets = group.filter((m) => may(m.pid));
19028
19102
  if (targets.length === 0 && group.length > 0) throw new KernelError("EPERM");
19029
19103
  const pids = new Set(targets.map((m) => m.pid));
19030
19104
  if (sig !== 0) {
19031
19105
  for (const m of targets)
19032
- if (m.execParent === void 0 || !pids.has(m.execParent)) m.signal(sig);
19106
+ if (m.execParent === void 0 || !pids.has(m.execParent)) m.signal(sig, info);
19033
19107
  }
19034
19108
  return targets.length > 0;
19035
19109
  }
@@ -22368,7 +22442,8 @@ function childHandle(handle) {
22368
22442
  pid: handle.pid,
22369
22443
  exited: handle.exited,
22370
22444
  termsig: handle.termsig,
22371
- onState: (listener) => handle.onState(listener)
22445
+ onState: (listener) => handle.onState(listener),
22446
+ uid: () => handle.cred?.().ruid
22372
22447
  };
22373
22448
  }
22374
22449
  function concat7(chunks2) {
@@ -23406,7 +23481,7 @@ var Launcher = class {
23406
23481
  onError: req.report,
23407
23482
  spawner: this.spawner(pid, req.report),
23408
23483
  forker: this.forker(pid, req),
23409
- kill: (target, sig) => this.kill(target, sig, this.credOf(pid), pid),
23484
+ kill: (target, sig, info) => this.kill(target, sig, this.credOf(pid), pid, info),
23410
23485
  writesBack: (target) => this.processes.get(target)?.writesBack() === true,
23411
23486
  processes: () => ({
23412
23487
  boot: this.boot,
@@ -23441,7 +23516,7 @@ var Launcher = class {
23441
23516
  this.creds.set(pid, () => handle.cred?.() ?? copyCred(cred));
23442
23517
  this.marks(pid, req);
23443
23518
  if (req.ppid !== void 0 && this.controlsJobs(req.ppid)) this.settling.started(pid, req.ppid);
23444
- this.jobs.add(pid, req.ppid, (sig) => handle.signal(sig), terminal);
23519
+ this.jobs.add(pid, req.ppid, (sig, info) => handle.signal(sig, info), terminal);
23445
23520
  if (req.exec && req.ppid !== void 0) this.jobs.exec(req.ppid, pid, true);
23446
23521
  if (req.pgid !== void 0) this.jobs.join(pid, req.pgid);
23447
23522
  if (req.group === "lead") this.jobs.lead(pid);
@@ -23822,21 +23897,26 @@ var Launcher = class {
23822
23897
  ignoredBy(pid, fork = false) {
23823
23898
  return this.processes.get(pid)?.ignoredSignals(fork) ?? 0;
23824
23899
  }
23825
- kill(pid, sig, sender, from) {
23900
+ kill(pid, sig, sender, from, forwarded) {
23901
+ const info = forwarded ?? this.senderInfo(sender, from);
23826
23902
  const session = from === void 0 ? void 0 : this.jobs.sidOf(from);
23827
23903
  const may = (target) => !sender || maySignal(sender, this.credOf(target)) || sig === SIG.CONT && session !== void 0 && this.jobs.sidOf(target) === session || from !== void 0 && this.imageOf(from) === this.imageOf(target) || from !== void 0 && this.granted.get(this.jobs.shown(target)) === from || from !== void 0 && this.granted.get(this.jobs.pgidOf(target) ?? 0) === from;
23828
23904
  if (pid === -1) {
23829
23905
  const sender2 = from === void 0 ? void 0 : this.imageOf(from);
23830
- return this.killAll(sig, (member) => this.imageOf(member) !== sender2, may);
23906
+ return this.killAll(sig, (member) => this.imageOf(member) !== sender2, may, info);
23831
23907
  }
23832
- if (pid < 0) return this.jobs.killGroup(-pid, sig, (member) => may(this.imageOf(member)));
23908
+ if (pid < 0) return this.jobs.killGroup(-pid, sig, (member) => may(this.imageOf(member)), info);
23833
23909
  const handle = this.processes.get(pid);
23834
23910
  if (!handle) return false;
23835
23911
  if (!may(this.imageOf(pid))) throw fsError("EPERM", `pid ${pid}`);
23836
- if (sig !== 0) handle.signal(sig);
23912
+ if (sig !== 0) handle.signal(sig, info);
23837
23913
  return true;
23838
23914
  }
23839
- killAll(sig, other, may) {
23915
+ senderInfo(sender, from) {
23916
+ if (from === void 0) return void 0;
23917
+ return { code: SI.USER, pid: this.jobs.shown(from), uid: sender?.ruid ?? 0, status: 0 };
23918
+ }
23919
+ killAll(sig, other, may, info) {
23840
23920
  const candidates = [...this.processes].filter(([pid]) => pid !== 1 && other(pid));
23841
23921
  const targets = candidates.filter(([pid]) => may(this.imageOf(pid)));
23842
23922
  if (targets.length === 0 && candidates.length > 0) throw fsError("EPERM", "kill -1");
@@ -23844,7 +23924,7 @@ var Launcher = class {
23844
23924
  const parents = new Map(this.jobs.list().map((m) => [m.pid, m.execParent]));
23845
23925
  for (const [pid, handle] of targets) {
23846
23926
  const parent = parents.get(pid);
23847
- if (sig !== 0 && (parent === void 0 || !pids.has(parent))) handle.signal(sig);
23927
+ if (sig !== 0 && (parent === void 0 || !pids.has(parent))) handle.signal(sig, info);
23848
23928
  }
23849
23929
  return targets.length > 0;
23850
23930
  }