@ai-ecoverse/slicc-kernel 1.48.0 → 1.48.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.
@@ -1673,7 +1673,7 @@ function ptyStat(path) {
1673
1673
  function nonblocking(stream) {
1674
1674
  return (stream.flags & O_NONBLOCK) !== 0 ? { nonblock: true } : void 0;
1675
1675
  }
1676
- var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
1676
+ var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
1677
1677
  var init_kernel_streams = __esm({
1678
1678
  "src/process/kernel-streams.ts"() {
1679
1679
  "use strict";
@@ -1684,6 +1684,7 @@ var init_kernel_streams = __esm({
1684
1684
  POLLHUP = 16;
1685
1685
  POLLRDNORM = 64;
1686
1686
  POLLWRNORM = 256;
1687
+ TCSETSF = 21508;
1687
1688
  O_NONBLOCK = 2048;
1688
1689
  SOCKET_MODE = 49663;
1689
1690
  PTY_PATH = /^\/dev\/(?:ptmx|pts\/(\d+))$/;
@@ -1802,8 +1803,8 @@ var init_kernel_streams = __esm({
1802
1803
  return {
1803
1804
  ops: {
1804
1805
  ioctl_tcgets: () => this.call(() => this.sys.tcgets?.(kfd)),
1805
- ioctl_tcsets: (_tty, _op, termios) => this.call(() => {
1806
- this.sys.tcsets?.(kfd, termios);
1806
+ ioctl_tcsets: (_tty, op, termios) => this.call(() => {
1807
+ this.sys.tcsets?.(kfd, termios, op === TCSETSF);
1807
1808
  return 0;
1808
1809
  }),
1809
1810
  ioctl_tiocgwinsz: () => this.call(() => this.sys.winsize?.(kfd) ?? [24, 80]),
@@ -3926,8 +3927,8 @@ function kernelSys(transport) {
3926
3927
  tcgets(fd) {
3927
3928
  return json(call2({ op: "tty-get", fd }, `tty-get ${fd}`));
3928
3929
  },
3929
- tcsets(fd, termios) {
3930
- call2({ op: "tty-set", fd, termios }, `tty-set ${fd}`);
3930
+ tcsets(fd, termios, flush) {
3931
+ call2({ op: "tty-set", fd, termios, ...flush ? { flush } : {} }, `tty-set ${fd}`);
3931
3932
  },
3932
3933
  winsize(fd) {
3933
3934
  return json(call2({ op: "tty-winsz", fd }, `tty-winsz ${fd}`));
@@ -5499,7 +5500,7 @@ function sliccTty(mem, fds, kernel) {
5499
5500
  if (actions < 0 || actions > TCSAFLUSH) throw new WasiError("EINVAL");
5500
5501
  const at = terminal(fd);
5501
5502
  needs(sys.tcsets);
5502
- sys.tcsets?.(at, readTermios(mem, ptr));
5503
+ sys.tcsets?.(at, readTermios(mem, ptr), actions === TCSAFLUSH);
5503
5504
  };
5504
5505
  const size = (fd, ptr) => {
5505
5506
  const [rows, cols] = needs(sys.winsize?.(terminal(fd)));
@@ -5551,7 +5552,6 @@ function kernelFiletype(kind) {
5551
5552
  case "device":
5552
5553
  return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
5553
5554
  case "socket":
5554
- case "stream":
5555
5555
  return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
5556
5556
  case "file":
5557
5557
  return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
@@ -5588,7 +5588,7 @@ function wrap(table) {
5588
5588
  }
5589
5589
  return out;
5590
5590
  }
5591
- var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
5591
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
5592
5592
  var init_wasi_host = __esm({
5593
5593
  "src/process/wasi/wasi-host.ts"() {
5594
5594
  "use strict";
@@ -5609,6 +5609,7 @@ var init_wasi_host = __esm({
5609
5609
  IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
5610
5610
  NS_PER_MS = 1000000n;
5611
5611
  AT_SYMLINK_NOFOLLOW2 = 1;
5612
+ S_IFIFO = 4096;
5612
5613
  DEFAULT_UMASK = 18;
5613
5614
  MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
5614
5615
  MAX_READ = 1024 * 1024;
@@ -5685,7 +5686,12 @@ var init_wasi_host = __esm({
5685
5686
  const old = this.o.kernel.call({ op: "proc-umask", mask });
5686
5687
  mem.view().setUint32(out, old, true);
5687
5688
  },
5688
- fd_mode: (fd, out) => void mem.view().setUint32(out, modeOf(this.o.fs.stat(pathOf(fd))), true),
5689
+ fd_mode: (fd, out) => {
5690
+ const e = fds.get(fd);
5691
+ const pipe = e.type === "kernel" && fds.kind(fd, e) === "stream";
5692
+ const mode = pipe ? S_IFIFO | 384 : modeOf(this.o.fs.stat(pathOf(fd)));
5693
+ mem.view().setUint32(out, mode, true);
5694
+ },
5689
5695
  path_mode: (dirfd, p, l, flags, out) => {
5690
5696
  const path = at(dirfd, p, l);
5691
5697
  const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
@@ -5778,8 +5784,8 @@ var init_wasi_host = __esm({
5778
5784
  return BigInt(Math.round((performance.now() - this.started) * 1e6)) + 1n;
5779
5785
  }
5780
5786
  environ() {
5781
- const listen = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
5782
- const env = { PWD: this.cwd, ...this.o.env, ...listen };
5787
+ const listen2 = this.listening.length > 0 ? { SLICC_LISTEN_FDS: this.listening.join(" ") } : {};
5788
+ const env = { PWD: this.cwd, ...this.o.env, ...listen2 };
5783
5789
  return Object.entries(env).map(([k, v]) => `${k}=${v}`);
5784
5790
  }
5785
5791
  processImports() {
@@ -6315,7 +6321,7 @@ function restarted2(issue) {
6315
6321
  function resolveFrom(cwd, path) {
6316
6322
  return normalize(path.startsWith("/") ? path : `${cwd}/${path}`);
6317
6323
  }
6318
- var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, WasixProcess;
6324
+ var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, JOIN_NON_BLOCKING, JOIN_WAKE_STOPPED, JOIN_STOPPED, WasixProcess;
6319
6325
  var init_wasix_process = __esm({
6320
6326
  "src/process/wasi/wasix-process.ts"() {
6321
6327
  "use strict";
@@ -6327,6 +6333,9 @@ var init_wasix_process = __esm({
6327
6333
  O_APPEND2 = 1024;
6328
6334
  OFLAG_CREAT = 1;
6329
6335
  OFLAG_TRUNC = 8;
6336
+ JOIN_NON_BLOCKING = 1;
6337
+ JOIN_WAKE_STOPPED = 2;
6338
+ JOIN_STOPPED = 3;
6330
6339
  WasixProcess = class {
6331
6340
  host;
6332
6341
  driver;
@@ -6456,13 +6465,21 @@ var init_wasix_process = __esm({
6456
6465
  const v = this.host.mem.view();
6457
6466
  const pid = v.getUint8(pidPtr) === 1 ? v.getUint32(pidPtr + 4, true) : -1;
6458
6467
  this.host.mem.bytes(statusPtr, 6).fill(0);
6459
- const [child, status2] = this.call({ op: "proc-wait", pid, nohang: (flags & 1) !== 0 });
6468
+ const [child, status2] = this.call({
6469
+ op: "proc-wait",
6470
+ pid,
6471
+ nohang: (flags & JOIN_NON_BLOCKING) !== 0,
6472
+ ...flags & JOIN_WAKE_STOPPED ? { untraced: true } : {}
6473
+ });
6460
6474
  if (child === 0) return;
6461
6475
  this.host.o.fs.invalidate?.();
6462
6476
  v.setUint8(pidPtr, 1);
6463
6477
  v.setUint32(pidPtr + 4, child, true);
6464
6478
  const sig = status2 & 127;
6465
- if (sig) {
6479
+ if (sig === 127) {
6480
+ v.setUint8(statusPtr, JOIN_STOPPED);
6481
+ v.setUint8(statusPtr + 2, status2 >> 8 & 255);
6482
+ } else if (sig) {
6466
6483
  v.setUint8(statusPtr, 2);
6467
6484
  v.setUint8(statusPtr + 4, sig);
6468
6485
  } else {
@@ -8989,6 +9006,56 @@ function latin1(bytes) {
8989
9006
  }
8990
9007
  return text;
8991
9008
  }
9009
+ function quoted(input, from) {
9010
+ let value2 = "";
9011
+ let at = from + 1;
9012
+ while (at < input.length) {
9013
+ const char = input[at++];
9014
+ if (char === '"') break;
9015
+ if (char !== "\\") value2 += char;
9016
+ else if (at < input.length) value2 += input[at++];
9017
+ else value2 += char;
9018
+ }
9019
+ return [value2, at];
9020
+ }
9021
+ function parameter(text, from, params) {
9022
+ let at = from + 1;
9023
+ while (SPACE.test(text[at] ?? "")) at++;
9024
+ let end = at;
9025
+ while (end < text.length && text[end] !== ";" && text[end] !== "=") end++;
9026
+ const name = text.slice(at, end).toLowerCase();
9027
+ if (text[end] !== "=") return end;
9028
+ const start2 = end + 1;
9029
+ let value2;
9030
+ if (text[start2] === '"') {
9031
+ [value2, at] = quoted(text, start2);
9032
+ end = text.indexOf(";", at);
9033
+ } else {
9034
+ end = text.indexOf(";", start2);
9035
+ value2 = text.slice(start2, end < 0 ? void 0 : end).replace(/[\t\n\r ]+$/, "");
9036
+ if (!value2) return end < 0 ? text.length : end;
9037
+ }
9038
+ if (end < 0) end = text.length;
9039
+ if (TOKEN.test(name) && QUOTABLE.test(value2) && !params.has(name)) {
9040
+ params.set(name, value2);
9041
+ }
9042
+ return end;
9043
+ }
9044
+ function mimeType(input) {
9045
+ const text = input.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
9046
+ const slash = text.indexOf("/");
9047
+ const semi = text.indexOf(";", slash);
9048
+ const type = text.slice(0, slash);
9049
+ const subtype = text.slice(slash + 1, semi < 0 ? void 0 : semi).replace(/[\t\n\r ]+$/, "");
9050
+ if (slash < 0 || !TOKEN.test(type) || !TOKEN.test(subtype)) return void 0;
9051
+ const params = /* @__PURE__ */ new Map();
9052
+ for (let at = semi < 0 ? text.length : semi; at < text.length; ) at = parameter(text, at, params);
9053
+ let out = `${type}/${subtype}`.toLowerCase();
9054
+ for (const [name, value2] of params) {
9055
+ out += `;${name}=${TOKEN.test(value2) ? value2 : `"${value2.replace(/["\\]/g, "\\$&")}"`}`;
9056
+ }
9057
+ return out;
9058
+ }
8992
9059
  function dataResponse(request) {
8993
9060
  const url = withoutFragment(new URL(request.url));
8994
9061
  const rest2 = url.slice("data:".length);
@@ -8998,7 +9065,7 @@ function dataResponse(request) {
8998
9065
  let body = percentDecode(rest2.slice(comma + 1));
8999
9066
  const base642 = BASE64.exec(type);
9000
9067
  if (base642) {
9001
- type = type.slice(0, base642.index).replace(/[\t\n\f\r ]+$/, "");
9068
+ type = type.slice(0, base642.index);
9002
9069
  let binary;
9003
9070
  try {
9004
9071
  binary = atob(latin1(body));
@@ -9008,11 +9075,10 @@ function dataResponse(request) {
9008
9075
  body = Uint8Array.from(binary, (c) => c.charCodeAt(0));
9009
9076
  }
9010
9077
  if (type.startsWith(";")) type = `text/plain${type}`;
9011
- if (!MIME.test(type)) type = "text/plain;charset=US-ASCII";
9012
- const response = new Response(body, {
9013
- status: 200,
9014
- headers: { "content-type": type }
9015
- });
9078
+ const response = new Response(
9079
+ request.method === "HEAD" ? null : body,
9080
+ { status: 200, headers: { "content-type": mimeType(type) ?? "text/plain;charset=US-ASCII" } }
9081
+ );
9016
9082
  return withMeta(response, url, false);
9017
9083
  }
9018
9084
  function withMeta(response, url, redirected) {
@@ -9200,7 +9266,7 @@ function fetchOp(kernel) {
9200
9266
  }
9201
9267
  };
9202
9268
  }
9203
- var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, MIME, BASE64, SLICE;
9269
+ var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
9204
9270
  var init_js_fetch = __esm({
9205
9271
  "src/process/js/js-fetch.ts"() {
9206
9272
  "use strict";
@@ -9219,7 +9285,9 @@ var init_js_fetch = __esm({
9219
9285
  DECODED = /* @__PURE__ */ new Set(["gzip", "x-gzip", "deflate"]);
9220
9286
  CREDENTIALS = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2"]);
9221
9287
  OVER = /* @__PURE__ */ Symbol("over");
9222
- MIME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+(?:[\t ]*;.*)?$/s;
9288
+ TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
9289
+ QUOTABLE = /^[\t\x20-\x7e\x80-\xff]*$/;
9290
+ SPACE = /[\t\n\r ]/;
9223
9291
  BASE64 = /; *base64$/i;
9224
9292
  SLICE = 32768;
9225
9293
  }
@@ -9696,6 +9764,7 @@ function rawOf(termios) {
9696
9764
  }
9697
9765
  function ttyOps(kernel) {
9698
9766
  const saved = /* @__PURE__ */ new Map();
9767
+ const terminalOf = async (fd) => (await kernel.json({ op: "fd-info", fd })).terminal ?? `fd ${fd}`;
9699
9768
  const getAttr = async (fd) => await kernel.json({ op: "tty-get", fd });
9700
9769
  const setAttr = async (fd, termios) => {
9701
9770
  await kernel.call({ op: "tty-set", fd, termios: copy(termios) });
@@ -9704,14 +9773,15 @@ function ttyOps(kernel) {
9704
9773
  getAttr,
9705
9774
  setAttr,
9706
9775
  async setRaw(fd, raw) {
9776
+ const terminal = await terminalOf(fd);
9707
9777
  if (!raw) {
9708
- const original = saved.get(fd);
9709
- saved.delete(fd);
9710
- if (original) await setAttr(fd, original);
9778
+ const original = saved.get(terminal);
9779
+ saved.delete(terminal);
9780
+ if (original) await setAttr(fd, original.termios);
9711
9781
  return;
9712
9782
  }
9713
9783
  const current = await getAttr(fd);
9714
- if (!saved.has(fd)) saved.set(fd, current);
9784
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
9715
9785
  await setAttr(fd, rawOf(current));
9716
9786
  },
9717
9787
  async size(fd) {
@@ -9724,9 +9794,9 @@ function ttyOps(kernel) {
9724
9794
  }
9725
9795
  };
9726
9796
  const restore = async () => {
9727
- for (const [fd, original] of [...saved].reverse()) {
9728
- saved.delete(fd);
9729
- await setAttr(fd, original).catch(() => void 0);
9797
+ for (const [terminal, { fd, termios }] of [...saved].reverse()) {
9798
+ saved.delete(terminal);
9799
+ await setAttr(fd, termios).catch(() => void 0);
9730
9800
  }
9731
9801
  };
9732
9802
  return { tty, restore };
@@ -9905,6 +9975,11 @@ var init_js_websocket = __esm({
9905
9975
  });
9906
9976
 
9907
9977
  // src/process/js/js-context.ts
9978
+ function listen(listeners, listener) {
9979
+ const own = (error, promise) => listener(error, promise);
9980
+ listeners.add(own);
9981
+ return () => void listeners.delete(own);
9982
+ }
9908
9983
  function identityOf(answer2, fallback) {
9909
9984
  const id = answer2;
9910
9985
  return {
@@ -10026,6 +10101,7 @@ function createContext(o) {
10026
10101
  const terminal = ttyOps(kernel);
10027
10102
  const io = { read, send: writeAll, close: (fd) => ctx.close(fd) };
10028
10103
  const children = childOps(kernel, io, { env: o.env, cwd: o.cwd, signal: signalNumber });
10104
+ const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
10029
10105
  const ctx = {
10030
10106
  argv: o.argv,
10031
10107
  env: o.env,
@@ -10073,7 +10149,9 @@ function createContext(o) {
10073
10149
  net: netOps(kernel, io),
10074
10150
  websocket: websocketOp(kernel),
10075
10151
  tty: terminal.tty,
10076
- exit
10152
+ exit,
10153
+ onUncaught: (listener) => listen(strays.exception, listener),
10154
+ onUnhandledRejection: (listener) => listen(strays.rejection, listener)
10077
10155
  };
10078
10156
  const drain2 = async () => {
10079
10157
  for (; ; ) {
@@ -10292,19 +10370,19 @@ __export(js_runtime_exports, {
10292
10370
  runJsProcess: () => runJsProcess,
10293
10371
  trapStrays: () => trapStrays
10294
10372
  });
10295
- function trapStrays(scope2, fail) {
10373
+ function trapStrays(scope2, stray) {
10296
10374
  if (typeof scope2.process?.on === "function") {
10297
- scope2.process.on("unhandledRejection", fail);
10298
- scope2.process.on("uncaughtException", fail);
10375
+ scope2.process.on("unhandledRejection", (err, promise) => stray("rejection", err, promise));
10376
+ scope2.process.on("uncaughtException", (err) => stray("exception", err));
10299
10377
  return;
10300
10378
  }
10301
10379
  scope2.addEventListener?.("unhandledrejection", (event) => {
10302
10380
  event.preventDefault();
10303
- fail(event.reason);
10381
+ stray("rejection", event.reason, event.promise);
10304
10382
  });
10305
10383
  scope2.addEventListener?.("error", (event) => {
10306
10384
  event.preventDefault();
10307
- fail(event.error);
10385
+ stray("exception", event.error);
10308
10386
  });
10309
10387
  }
10310
10388
  async function settledStrays() {
@@ -10341,6 +10419,7 @@ async function runJsProcess(init, port2, deps = {}) {
10341
10419
  waitAsync: deps.waitAsync
10342
10420
  });
10343
10421
  void kernel.watchStops();
10422
+ const strays = { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
10344
10423
  const id = identityOf(await kernel.json({ op: "proc-identity" }), init);
10345
10424
  kernel.pid = id.pid;
10346
10425
  const { ctx, drain: drain2 } = createContext({
@@ -10351,12 +10430,23 @@ async function runJsProcess(init, port2, deps = {}) {
10351
10430
  ppid: id.ppid,
10352
10431
  cwd: init.cwd,
10353
10432
  exit: (status3) => exited(statusOf(status3)),
10354
- lane: laneOf(init.lane)
10433
+ lane: laneOf(init.lane),
10434
+ strays
10355
10435
  });
10356
10436
  const say = (text) => ctx.write(2, `${init.argv0}: ${text}
10357
10437
  `).catch(() => void 0);
10358
10438
  let main;
10359
- trapStrays(deps.scope ?? globalThis, fail);
10439
+ trapStrays(deps.scope ?? globalThis, (kind, err, promise) => {
10440
+ const listeners = [...strays[kind]];
10441
+ if (listeners.length === 0) return fail(err);
10442
+ for (const listener of listeners) {
10443
+ try {
10444
+ listener(err, promise);
10445
+ } catch (thrown) {
10446
+ fail(thrown);
10447
+ }
10448
+ }
10449
+ });
10360
10450
  try {
10361
10451
  (deps.lockdown ?? lockdown)();
10362
10452
  main = mainOf(await (deps.load ?? importSource)(init.program.glue));