@ai-ecoverse/slicc-kernel 1.113.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.
@@ -4962,6 +4962,14 @@ var SIGNAL_BY_NAME = {
4962
4962
  SIGSTOP: SIG.STOP,
4963
4963
  SIGCONT: SIG.CONT
4964
4964
  };
4965
+ var SI = { USER: 0, QUEUE: -1, TIMER: -2, TKILL: -6, KERNEL: 128 };
4966
+ var CLD = { EXITED: 1, KILLED: 2, DUMPED: 3, STOPPED: 5, CONTINUED: 6 };
4967
+ var KERNEL_SIGINFO = Object.freeze({
4968
+ code: SI.KERNEL,
4969
+ pid: 0,
4970
+ uid: 0,
4971
+ status: 0
4972
+ });
4965
4973
 
4966
4974
  // src/body-idle.ts
4967
4975
  var BODY_IDLE_MS = 5 * 60 * 1e3;
@@ -6213,7 +6221,7 @@ function satisfies(version, range2) {
6213
6221
  }
6214
6222
 
6215
6223
  // src/version.ts
6216
- var KERNEL_VERSION = true ? "1.113.0" : "0.0.0-dev";
6224
+ var KERNEL_VERSION = true ? "1.114.0" : "0.0.0-dev";
6217
6225
  var OS_RELEASE = "6.0.0-slicc";
6218
6226
  function procVersion() {
6219
6227
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9089,8 +9097,16 @@ var ChildTable = class {
9089
9097
  void handle.exited.then((code) => {
9090
9098
  child.code = code;
9091
9099
  this.watchers.delete(handle.pid);
9100
+ const termsig = handle.termsig?.();
9092
9101
  if (!this.kept.delete(handle.pid) && this.autoReap?.()) this.reap(handle.pid, code);
9093
- this.onChildState?.();
9102
+ const uid = handle.uid?.();
9103
+ this.onChildState?.({
9104
+ pid: handle.pid,
9105
+ state: "exited",
9106
+ status: termsig ?? code,
9107
+ termsig,
9108
+ uid
9109
+ });
9094
9110
  });
9095
9111
  handle.onState?.((state, sig) => {
9096
9112
  child.stopReport = state === "stopped" ? sig : void 0;
@@ -9100,7 +9116,7 @@ var ChildTable = class {
9100
9116
  const waiters = this.stateChanged;
9101
9117
  this.stateChanged = [];
9102
9118
  for (const wake of waiters) wake();
9103
- this.onChildState?.();
9119
+ this.onChildState?.({ pid: handle.pid, state, status: sig, uid: handle.uid?.() });
9104
9120
  });
9105
9121
  this.children.set(handle.pid, child);
9106
9122
  return handle.pid;
@@ -17170,6 +17186,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
17170
17186
  "sig-mask",
17171
17187
  "sig-inherited",
17172
17188
  "sig-waiting",
17189
+ "sig-info",
17173
17190
  "sig-pause",
17174
17191
  ...SOCKET_OPS,
17175
17192
  ...EPOLL_OPS,
@@ -17251,7 +17268,7 @@ var WasmProcess = class {
17251
17268
  this.children = new ChildTable(fds, options.spawner, options.forker);
17252
17269
  this.nodes = options.nodes ?? new VfsNodes(options.fs);
17253
17270
  if (!options.nodes) options.openFiles?.add(this.nodes);
17254
- this.children.onChildState = () => this.signal(SIG.CHLD);
17271
+ this.children.onChildState = (child) => this.signal(SIG.CHLD, child && this.childInfo(child));
17255
17272
  this.children.autoReap = () => this.reapsChildren();
17256
17273
  this.seedDl(options.dl);
17257
17274
  this.children.onReap = (pid2) => {
@@ -17268,10 +17285,43 @@ var WasmProcess = class {
17268
17285
  inheritable(fork = false) {
17269
17286
  return ((fork ? 0 : this.ignored) | this.inherited) & ~this.caught;
17270
17287
  }
17271
- signal(sig) {
17288
+ sigInfos = /* @__PURE__ */ new Map();
17289
+ signal(sig, info) {
17290
+ const pending = ((this.options.pendingBits?.() ?? 0) & sigbit(sig)) !== 0;
17291
+ const outcome = this.signalOutcome(sig, info);
17292
+ if (outcome === "deliver" && !(pending && this.sigInfos.has(`0:${sig}`))) {
17293
+ this.sigInfos.set(`0:${sig}`, info ?? KERNEL_SIGINFO);
17294
+ }
17295
+ return outcome;
17296
+ }
17297
+ async threadKill(tid, sig) {
17298
+ const info = await this.threadSender(sig);
17299
+ if (this.options.threadKill?.(tid, sig)) this.sigInfos.set(`${tid}:${sig}`, info);
17300
+ else this.options.raise?.(sig, info);
17301
+ }
17302
+ async threadSender(sig) {
17303
+ const pid = (await this.options.identity?.())?.pid ?? this.pid;
17304
+ const code = sig === SIG.PIPE ? SI.USER : SI.TKILL;
17305
+ return { code, pid, uid: this.cred.ruid, status: 0 };
17306
+ }
17307
+ childInfo(child) {
17308
+ const code = child.state === "stopped" ? CLD.STOPPED : child.state === "continued" ? CLD.CONTINUED : child.termsig ? CLD.KILLED : CLD.EXITED;
17309
+ return { code, pid: child.pid, uid: child.uid ?? this.cred.ruid, status: child.status };
17310
+ }
17311
+ takeSigInfo(sig, tid) {
17312
+ for (const key of [`${tid}:${sig}`, `0:${sig}`]) {
17313
+ const info = this.sigInfos.get(key);
17314
+ if (info) {
17315
+ this.sigInfos.delete(key);
17316
+ return info;
17317
+ }
17318
+ }
17319
+ return null;
17320
+ }
17321
+ signalOutcome(sig, info) {
17272
17322
  if (this.execChild !== void 0) {
17273
17323
  if (sig === SIG.CONT) this.cont();
17274
- void Promise.resolve(this.options.kill?.(this.execChild, sig)).catch(() => void 0);
17324
+ void Promise.resolve(this.options.kill?.(this.execChild, sig, info)).catch(() => void 0);
17275
17325
  if (sig !== SIG.KILL) return "forward";
17276
17326
  if (!this.options.writesBack?.(this.execChild)) return "terminate";
17277
17327
  this.wake?.();
@@ -18332,8 +18382,10 @@ var WasmProcess = class {
18332
18382
  case "sig-pause":
18333
18383
  return this.pause(cancelled);
18334
18384
  case "thread-kill":
18335
- if (!this.options.threadKill?.(req.tid, req.sig)) this.options.raise?.(req.sig);
18385
+ await this.threadKill(req.tid, req.sig);
18336
18386
  return { ok: true, kind: "void" };
18387
+ case "sig-info":
18388
+ return { ok: true, kind: "json", json: this.takeSigInfo(req.sig, req.tid ?? 0) };
18337
18389
  case "proc-captured":
18338
18390
  return { ok: true, kind: "bytes", bytes: this.children.captured(req.pid, req.slot) };
18339
18391
  case "proc-sudo":
@@ -18812,7 +18864,7 @@ function spawnWasmProcess(opts) {
18812
18864
  opts,
18813
18865
  header3,
18814
18866
  {
18815
- raise: (sig) => signal(sig),
18867
+ raise: (sig, info) => signal(sig, info),
18816
18868
  threadKill: (tid, sig) => killThread(threadSignals.get(tid), process.signalMasks().caught, sig),
18817
18869
  unblockedThread: (sig) => unblockedThread(threadSignals, sig),
18818
18870
  ...opts.program.abi === "js" ? {
@@ -18934,8 +18986,9 @@ function spawnWasmProcess(opts) {
18934
18986
  if (opts.program.abi !== "wasi" || done4) finish(code, sig);
18935
18987
  else dying.start(code, sig, header3, process, () => finish(code, sig));
18936
18988
  };
18937
- const signal = (sig) => {
18938
- if (process.signal(sig) === "terminate") terminate(sig === SIG.KILL ? 137 : 128 + sig, sig);
18989
+ const signal = (sig, info) => {
18990
+ if (process.signal(sig, info) === "terminate")
18991
+ terminate(sig === SIG.KILL ? 137 : 128 + sig, sig);
18939
18992
  };
18940
18993
  const kill = (code = 137) => finish(code, code > 128 && code < 160 ? code - 128 : void 0);
18941
18994
  return {
@@ -19105,14 +19158,14 @@ var JobTable = class {
19105
19158
  this.foreground.set(tty, member.pgid);
19106
19159
  return true;
19107
19160
  }
19108
- killGroup(pgid, sig, may = () => true) {
19161
+ killGroup(pgid, sig, may = () => true, info) {
19109
19162
  const group = [...this.members.values()].filter((m) => m.pgid === pgid);
19110
19163
  const targets = group.filter((m) => may(m.pid));
19111
19164
  if (targets.length === 0 && group.length > 0) throw new KernelError("EPERM");
19112
19165
  const pids = new Set(targets.map((m) => m.pid));
19113
19166
  if (sig !== 0) {
19114
19167
  for (const m of targets)
19115
- if (m.execParent === void 0 || !pids.has(m.execParent)) m.signal(sig);
19168
+ if (m.execParent === void 0 || !pids.has(m.execParent)) m.signal(sig, info);
19116
19169
  }
19117
19170
  return targets.length > 0;
19118
19171
  }
@@ -22383,7 +22436,8 @@ function childHandle(handle) {
22383
22436
  pid: handle.pid,
22384
22437
  exited: handle.exited,
22385
22438
  termsig: handle.termsig,
22386
- onState: (listener) => handle.onState(listener)
22439
+ onState: (listener) => handle.onState(listener),
22440
+ uid: () => handle.cred?.().ruid
22387
22441
  };
22388
22442
  }
22389
22443
  function concat7(chunks) {
@@ -23421,7 +23475,7 @@ var Launcher = class {
23421
23475
  onError: req.report,
23422
23476
  spawner: this.spawner(pid, req.report),
23423
23477
  forker: this.forker(pid, req),
23424
- kill: (target, sig) => this.kill(target, sig, this.credOf(pid), pid),
23478
+ kill: (target, sig, info) => this.kill(target, sig, this.credOf(pid), pid, info),
23425
23479
  writesBack: (target) => this.processes.get(target)?.writesBack() === true,
23426
23480
  processes: () => ({
23427
23481
  boot: this.boot,
@@ -23456,7 +23510,7 @@ var Launcher = class {
23456
23510
  this.creds.set(pid, () => handle.cred?.() ?? copyCred(cred));
23457
23511
  this.marks(pid, req);
23458
23512
  if (req.ppid !== void 0 && this.controlsJobs(req.ppid)) this.settling.started(pid, req.ppid);
23459
- this.jobs.add(pid, req.ppid, (sig) => handle.signal(sig), terminal);
23513
+ this.jobs.add(pid, req.ppid, (sig, info) => handle.signal(sig, info), terminal);
23460
23514
  if (req.exec && req.ppid !== void 0) this.jobs.exec(req.ppid, pid, true);
23461
23515
  if (req.pgid !== void 0) this.jobs.join(pid, req.pgid);
23462
23516
  if (req.group === "lead") this.jobs.lead(pid);
@@ -23837,21 +23891,26 @@ var Launcher = class {
23837
23891
  ignoredBy(pid, fork = false) {
23838
23892
  return this.processes.get(pid)?.ignoredSignals(fork) ?? 0;
23839
23893
  }
23840
- kill(pid, sig, sender, from) {
23894
+ kill(pid, sig, sender, from, forwarded) {
23895
+ const info = forwarded ?? this.senderInfo(sender, from);
23841
23896
  const session = from === void 0 ? void 0 : this.jobs.sidOf(from);
23842
23897
  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;
23843
23898
  if (pid === -1) {
23844
23899
  const sender2 = from === void 0 ? void 0 : this.imageOf(from);
23845
- return this.killAll(sig, (member) => this.imageOf(member) !== sender2, may);
23900
+ return this.killAll(sig, (member) => this.imageOf(member) !== sender2, may, info);
23846
23901
  }
23847
- if (pid < 0) return this.jobs.killGroup(-pid, sig, (member) => may(this.imageOf(member)));
23902
+ if (pid < 0) return this.jobs.killGroup(-pid, sig, (member) => may(this.imageOf(member)), info);
23848
23903
  const handle = this.processes.get(pid);
23849
23904
  if (!handle) return false;
23850
23905
  if (!may(this.imageOf(pid))) throw fsError("EPERM", `pid ${pid}`);
23851
- if (sig !== 0) handle.signal(sig);
23906
+ if (sig !== 0) handle.signal(sig, info);
23852
23907
  return true;
23853
23908
  }
23854
- killAll(sig, other, may) {
23909
+ senderInfo(sender, from) {
23910
+ if (from === void 0) return void 0;
23911
+ return { code: SI.USER, pid: this.jobs.shown(from), uid: sender?.ruid ?? 0, status: 0 };
23912
+ }
23913
+ killAll(sig, other, may, info) {
23855
23914
  const candidates = [...this.processes].filter(([pid]) => pid !== 1 && other(pid));
23856
23915
  const targets = candidates.filter(([pid]) => may(this.imageOf(pid)));
23857
23916
  if (targets.length === 0 && candidates.length > 0) throw fsError("EPERM", "kill -1");
@@ -23859,7 +23918,7 @@ var Launcher = class {
23859
23918
  const parents = new Map(this.jobs.list().map((m) => [m.pid, m.execParent]));
23860
23919
  for (const [pid, handle] of targets) {
23861
23920
  const parent = parents.get(pid);
23862
- if (sig !== 0 && (parent === void 0 || !pids.has(parent))) handle.signal(sig);
23921
+ if (sig !== 0 && (parent === void 0 || !pids.has(parent))) handle.signal(sig, info);
23863
23922
  }
23864
23923
  return targets.length > 0;
23865
23924
  }