@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.
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;
@@ -6531,7 +6539,7 @@ function satisfies(version, range2) {
6531
6539
  }
6532
6540
 
6533
6541
  // src/version.ts
6534
- var KERNEL_VERSION = true ? "1.113.0" : "0.0.0-dev";
6542
+ var KERNEL_VERSION = true ? "1.114.0" : "0.0.0-dev";
6535
6543
  var OS_RELEASE = "6.0.0-slicc";
6536
6544
  function procVersion() {
6537
6545
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -9185,8 +9193,16 @@ var ChildTable = class {
9185
9193
  void handle.exited.then((code) => {
9186
9194
  child.code = code;
9187
9195
  this.watchers.delete(handle.pid);
9196
+ const termsig = handle.termsig?.();
9188
9197
  if (!this.kept.delete(handle.pid) && this.autoReap?.()) this.reap(handle.pid, code);
9189
- 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
+ });
9190
9206
  });
9191
9207
  handle.onState?.((state, sig) => {
9192
9208
  child.stopReport = state === "stopped" ? sig : void 0;
@@ -9196,7 +9212,7 @@ var ChildTable = class {
9196
9212
  const waiters = this.stateChanged;
9197
9213
  this.stateChanged = [];
9198
9214
  for (const wake of waiters) wake();
9199
- this.onChildState?.();
9215
+ this.onChildState?.({ pid: handle.pid, state, status: sig, uid: handle.uid?.() });
9200
9216
  });
9201
9217
  this.children.set(handle.pid, child);
9202
9218
  return handle.pid;
@@ -17108,6 +17124,7 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
17108
17124
  "sig-mask",
17109
17125
  "sig-inherited",
17110
17126
  "sig-waiting",
17127
+ "sig-info",
17111
17128
  "sig-pause",
17112
17129
  ...SOCKET_OPS,
17113
17130
  ...EPOLL_OPS,
@@ -17189,7 +17206,7 @@ var WasmProcess = class {
17189
17206
  this.children = new ChildTable(fds, options.spawner, options.forker);
17190
17207
  this.nodes = options.nodes ?? new VfsNodes(options.fs);
17191
17208
  if (!options.nodes) options.openFiles?.add(this.nodes);
17192
- this.children.onChildState = () => this.signal(SIG.CHLD);
17209
+ this.children.onChildState = (child) => this.signal(SIG.CHLD, child && this.childInfo(child));
17193
17210
  this.children.autoReap = () => this.reapsChildren();
17194
17211
  this.seedDl(options.dl);
17195
17212
  this.children.onReap = (pid2) => {
@@ -17206,10 +17223,43 @@ var WasmProcess = class {
17206
17223
  inheritable(fork = false) {
17207
17224
  return ((fork ? 0 : this.ignored) | this.inherited) & ~this.caught;
17208
17225
  }
17209
- 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) {
17210
17260
  if (this.execChild !== void 0) {
17211
17261
  if (sig === SIG.CONT) this.cont();
17212
- 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);
17213
17263
  if (sig !== SIG.KILL) return "forward";
17214
17264
  if (!this.options.writesBack?.(this.execChild)) return "terminate";
17215
17265
  this.wake?.();
@@ -18270,8 +18320,10 @@ var WasmProcess = class {
18270
18320
  case "sig-pause":
18271
18321
  return this.pause(cancelled);
18272
18322
  case "thread-kill":
18273
- if (!this.options.threadKill?.(req.tid, req.sig)) this.options.raise?.(req.sig);
18323
+ await this.threadKill(req.tid, req.sig);
18274
18324
  return { ok: true, kind: "void" };
18325
+ case "sig-info":
18326
+ return { ok: true, kind: "json", json: this.takeSigInfo(req.sig, req.tid ?? 0) };
18275
18327
  case "proc-captured":
18276
18328
  return { ok: true, kind: "bytes", bytes: this.children.captured(req.pid, req.slot) };
18277
18329
  case "proc-sudo":
@@ -18750,7 +18802,7 @@ function spawnWasmProcess(opts) {
18750
18802
  opts,
18751
18803
  header4,
18752
18804
  {
18753
- raise: (sig) => signal(sig),
18805
+ raise: (sig, info) => signal(sig, info),
18754
18806
  threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig),
18755
18807
  unblockedThread: (sig) => unblockedThread(threadSignals, sig),
18756
18808
  ...opts.program.abi === "js" ? {
@@ -18872,8 +18924,9 @@ function spawnWasmProcess(opts) {
18872
18924
  if (opts.program.abi !== "wasi" || done4) finish(code, sig);
18873
18925
  else dying.start(code, sig, header4, process2, () => finish(code, sig));
18874
18926
  };
18875
- const signal = (sig) => {
18876
- 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);
18877
18930
  };
18878
18931
  const kill = (code = 137) => finish(code, code > 128 && code < 160 ? code - 128 : void 0);
18879
18932
  return {
@@ -19043,14 +19096,14 @@ var JobTable = class {
19043
19096
  this.foreground.set(tty, member.pgid);
19044
19097
  return true;
19045
19098
  }
19046
- killGroup(pgid, sig, may = () => true) {
19099
+ killGroup(pgid, sig, may = () => true, info) {
19047
19100
  const group = [...this.members.values()].filter((m) => m.pgid === pgid);
19048
19101
  const targets = group.filter((m) => may(m.pid));
19049
19102
  if (targets.length === 0 && group.length > 0) throw new KernelError("EPERM");
19050
19103
  const pids = new Set(targets.map((m) => m.pid));
19051
19104
  if (sig !== 0) {
19052
19105
  for (const m of targets)
19053
- 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);
19054
19107
  }
19055
19108
  return targets.length > 0;
19056
19109
  }
@@ -22389,7 +22442,8 @@ function childHandle(handle) {
22389
22442
  pid: handle.pid,
22390
22443
  exited: handle.exited,
22391
22444
  termsig: handle.termsig,
22392
- onState: (listener) => handle.onState(listener)
22445
+ onState: (listener) => handle.onState(listener),
22446
+ uid: () => handle.cred?.().ruid
22393
22447
  };
22394
22448
  }
22395
22449
  function concat7(chunks2) {
@@ -23427,7 +23481,7 @@ var Launcher = class {
23427
23481
  onError: req.report,
23428
23482
  spawner: this.spawner(pid, req.report),
23429
23483
  forker: this.forker(pid, req),
23430
- 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),
23431
23485
  writesBack: (target) => this.processes.get(target)?.writesBack() === true,
23432
23486
  processes: () => ({
23433
23487
  boot: this.boot,
@@ -23462,7 +23516,7 @@ var Launcher = class {
23462
23516
  this.creds.set(pid, () => handle.cred?.() ?? copyCred(cred));
23463
23517
  this.marks(pid, req);
23464
23518
  if (req.ppid !== void 0 && this.controlsJobs(req.ppid)) this.settling.started(pid, req.ppid);
23465
- 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);
23466
23520
  if (req.exec && req.ppid !== void 0) this.jobs.exec(req.ppid, pid, true);
23467
23521
  if (req.pgid !== void 0) this.jobs.join(pid, req.pgid);
23468
23522
  if (req.group === "lead") this.jobs.lead(pid);
@@ -23843,21 +23897,26 @@ var Launcher = class {
23843
23897
  ignoredBy(pid, fork = false) {
23844
23898
  return this.processes.get(pid)?.ignoredSignals(fork) ?? 0;
23845
23899
  }
23846
- kill(pid, sig, sender, from) {
23900
+ kill(pid, sig, sender, from, forwarded) {
23901
+ const info = forwarded ?? this.senderInfo(sender, from);
23847
23902
  const session = from === void 0 ? void 0 : this.jobs.sidOf(from);
23848
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;
23849
23904
  if (pid === -1) {
23850
23905
  const sender2 = from === void 0 ? void 0 : this.imageOf(from);
23851
- return this.killAll(sig, (member) => this.imageOf(member) !== sender2, may);
23906
+ return this.killAll(sig, (member) => this.imageOf(member) !== sender2, may, info);
23852
23907
  }
23853
- 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);
23854
23909
  const handle = this.processes.get(pid);
23855
23910
  if (!handle) return false;
23856
23911
  if (!may(this.imageOf(pid))) throw fsError("EPERM", `pid ${pid}`);
23857
- if (sig !== 0) handle.signal(sig);
23912
+ if (sig !== 0) handle.signal(sig, info);
23858
23913
  return true;
23859
23914
  }
23860
- 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) {
23861
23920
  const candidates = [...this.processes].filter(([pid]) => pid !== 1 && other(pid));
23862
23921
  const targets = candidates.filter(([pid]) => may(this.imageOf(pid)));
23863
23922
  if (targets.length === 0 && candidates.length > 0) throw fsError("EPERM", "kill -1");
@@ -23865,7 +23924,7 @@ var Launcher = class {
23865
23924
  const parents = new Map(this.jobs.list().map((m) => [m.pid, m.execParent]));
23866
23925
  for (const [pid, handle] of targets) {
23867
23926
  const parent = parents.get(pid);
23868
- 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);
23869
23928
  }
23870
23929
  return targets.length > 0;
23871
23930
  }