@ai-ecoverse/slicc-kernel 1.47.3 → 1.48.1

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}`));
@@ -5460,6 +5461,75 @@ var init_wasi_poll = __esm({
5460
5461
  }
5461
5462
  });
5462
5463
 
5464
+ // src/process/wasi/wasi-termios.ts
5465
+ function writeTermios(mem, ptr, termios) {
5466
+ mem.bytes(ptr, OSPEED + 4).fill(0);
5467
+ const v = mem.view();
5468
+ v.setUint32(ptr, termios.c_iflag, true);
5469
+ v.setUint32(ptr + 4, termios.c_oflag, true);
5470
+ v.setUint32(ptr + 8, termios.c_cflag, true);
5471
+ v.setUint32(ptr + 12, termios.c_lflag, true);
5472
+ for (let i = 0; i < NCCS; i++) v.setUint8(ptr + C_CC + i, termios.c_cc[i] ?? 0);
5473
+ v.setUint8(ptr + C_LINE, 0);
5474
+ v.setUint32(ptr + ISPEED, B38400, true);
5475
+ v.setUint32(ptr + OSPEED, B38400, true);
5476
+ }
5477
+ function readTermios(mem, ptr) {
5478
+ const v = mem.view();
5479
+ return {
5480
+ c_iflag: v.getUint32(ptr, true),
5481
+ c_oflag: v.getUint32(ptr + 4, true),
5482
+ c_cflag: v.getUint32(ptr + 8, true),
5483
+ c_lflag: v.getUint32(ptr + 12, true),
5484
+ c_cc: Array.from({ length: NCCS }, (_, i) => v.getUint8(ptr + C_CC + i))
5485
+ };
5486
+ }
5487
+ function sliccTty(mem, fds, kernel) {
5488
+ const { sys } = kernel;
5489
+ const terminal = (fd) => {
5490
+ const e = fds.find(fd);
5491
+ if (!e) throw new WasiError("EBADF");
5492
+ if (e.type !== "kernel" || fds.kind(fd, e) !== "tty") throw new WasiError("ENOTTY");
5493
+ return fd;
5494
+ };
5495
+ const needs = (value2) => {
5496
+ if (value2 === void 0) throw new WasiError("ENOTTY");
5497
+ return value2;
5498
+ };
5499
+ const setAttr = (fd, actions, ptr) => {
5500
+ if (actions < 0 || actions > TCSAFLUSH) throw new WasiError("EINVAL");
5501
+ const at = terminal(fd);
5502
+ needs(sys.tcsets);
5503
+ sys.tcsets?.(at, readTermios(mem, ptr), actions === TCSAFLUSH);
5504
+ };
5505
+ const size = (fd, ptr) => {
5506
+ const [rows, cols] = needs(sys.winsize?.(terminal(fd)));
5507
+ mem.bytes(ptr, 8).fill(0);
5508
+ const v = mem.view();
5509
+ v.setUint16(ptr, rows, true);
5510
+ v.setUint16(ptr + 2, cols, true);
5511
+ };
5512
+ return {
5513
+ tcgetattr: (fd, ptr) => void writeTermios(mem, ptr, needs(sys.tcgets?.(terminal(fd)))),
5514
+ tcsetattr: (fd, actions, ptr) => void setAttr(fd, actions, ptr),
5515
+ winsize: (fd, ptr) => void size(fd, ptr)
5516
+ };
5517
+ }
5518
+ var NCCS, C_LINE, C_CC, ISPEED, OSPEED, B38400, TCSAFLUSH;
5519
+ var init_wasi_termios = __esm({
5520
+ "src/process/wasi/wasi-termios.ts"() {
5521
+ "use strict";
5522
+ init_wasi_files();
5523
+ NCCS = 32;
5524
+ C_LINE = 16;
5525
+ C_CC = 17;
5526
+ ISPEED = 52;
5527
+ OSPEED = 56;
5528
+ B38400 = 15;
5529
+ TCSAFLUSH = 2;
5530
+ }
5531
+ });
5532
+
5463
5533
  // src/process/wasi/wasi-host.ts
5464
5534
  function filetypeOf(s) {
5465
5535
  if (!s) return FILETYPE.UNKNOWN;
@@ -5529,6 +5599,7 @@ var init_wasi_host = __esm({
5529
5599
  init_wasi_files();
5530
5600
  init_wasi_memory();
5531
5601
  init_wasi_poll();
5602
+ init_wasi_termios();
5532
5603
  WasiExit = class extends Error {
5533
5604
  code;
5534
5605
  constructor(code2) {
@@ -5587,6 +5658,9 @@ var init_wasi_host = __esm({
5587
5658
  const umask = this.o.kernel.call({ op: "proc-umask" });
5588
5659
  if (umask !== DEFAULT_UMASK) this.o.fs.chmod(path, mode & ~umask);
5589
5660
  }
5661
+ sliccTtyImports() {
5662
+ return wrap(sliccTty(this.mem, this.fds, this.o.kernel));
5663
+ }
5590
5664
  sliccFsImports() {
5591
5665
  const { mem, fds } = this;
5592
5666
  const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
@@ -6242,7 +6316,7 @@ function restarted2(issue) {
6242
6316
  function resolveFrom(cwd, path) {
6243
6317
  return normalize(path.startsWith("/") ? path : `${cwd}/${path}`);
6244
6318
  }
6245
- var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, WasixProcess;
6319
+ var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, JOIN_NON_BLOCKING, JOIN_WAKE_STOPPED, JOIN_STOPPED, WasixProcess;
6246
6320
  var init_wasix_process = __esm({
6247
6321
  "src/process/wasi/wasix-process.ts"() {
6248
6322
  "use strict";
@@ -6254,6 +6328,9 @@ var init_wasix_process = __esm({
6254
6328
  O_APPEND2 = 1024;
6255
6329
  OFLAG_CREAT = 1;
6256
6330
  OFLAG_TRUNC = 8;
6331
+ JOIN_NON_BLOCKING = 1;
6332
+ JOIN_WAKE_STOPPED = 2;
6333
+ JOIN_STOPPED = 3;
6257
6334
  WasixProcess = class {
6258
6335
  host;
6259
6336
  driver;
@@ -6383,13 +6460,21 @@ var init_wasix_process = __esm({
6383
6460
  const v = this.host.mem.view();
6384
6461
  const pid = v.getUint8(pidPtr) === 1 ? v.getUint32(pidPtr + 4, true) : -1;
6385
6462
  this.host.mem.bytes(statusPtr, 6).fill(0);
6386
- const [child, status2] = this.call({ op: "proc-wait", pid, nohang: (flags & 1) !== 0 });
6463
+ const [child, status2] = this.call({
6464
+ op: "proc-wait",
6465
+ pid,
6466
+ nohang: (flags & JOIN_NON_BLOCKING) !== 0,
6467
+ ...flags & JOIN_WAKE_STOPPED ? { untraced: true } : {}
6468
+ });
6387
6469
  if (child === 0) return;
6388
6470
  this.host.o.fs.invalidate?.();
6389
6471
  v.setUint8(pidPtr, 1);
6390
6472
  v.setUint32(pidPtr + 4, child, true);
6391
6473
  const sig = status2 & 127;
6392
- if (sig) {
6474
+ if (sig === 127) {
6475
+ v.setUint8(statusPtr, JOIN_STOPPED);
6476
+ v.setUint8(statusPtr + 2, status2 >> 8 & 255);
6477
+ } else if (sig) {
6393
6478
  v.setUint8(statusPtr, 2);
6394
6479
  v.setUint8(statusPtr + 4, sig);
6395
6480
  } else {
@@ -7929,11 +8014,7 @@ var init_wasix_host = __esm({
7929
8014
  v.setUint8(ptr + 16, isTty(0));
7930
8015
  v.setUint8(ptr + 17, isTty(1));
7931
8016
  v.setUint8(ptr + 18, isTty(2));
7932
- if (fd === void 0) {
7933
- v.setUint32(ptr, 80, true);
7934
- v.setUint32(ptr + 4, 24, true);
7935
- return;
7936
- }
8017
+ if (fd === void 0) throw new WasiError("ENOTTY");
7937
8018
  const [rows, cols] = host.o.kernel.sys.winsize?.(fd) ?? [24, 80];
7938
8019
  const termios = host.o.kernel.sys.tcgets?.(fd);
7939
8020
  v.setUint32(ptr, cols, true);
@@ -8082,15 +8163,16 @@ function unsupportedImport(module, memory, extended = false, foreign = {}) {
8082
8163
  }
8083
8164
  return void 0;
8084
8165
  }
8085
- function linkImports(module, preview1, wasix, memory, threads, program = {}, foreign, slicc = {}, sliccFs = {}) {
8166
+ function linkImports(module, preview1, wasix, memory, threads, program = {}, foreign, slicc = {}, sliccFs = {}, sliccTty2 = {}) {
8086
8167
  for (const ns of Object.keys(program)) {
8087
- if (RESERVED2.has(ns) || ns === SLICC || ns === SLICC_FS)
8168
+ if (RESERVED2.has(ns) || ns === SLICC || ns === SLICC_FS || ns === SLICC_TTY)
8088
8169
  throw new Error(`the imports module may not define ${ns}`);
8089
8170
  }
8090
8171
  const imports = {
8091
8172
  ...program,
8092
8173
  [SLICC]: { ...slicc },
8093
8174
  [SLICC_FS]: { ...sliccFs },
8175
+ [SLICC_TTY]: { ...sliccTty2 },
8094
8176
  [PREVIEW1]: preview1,
8095
8177
  ...wasix ? { [WASIX]: { ...wasix } } : {},
8096
8178
  ...threads ? { wasi: { "thread-spawn": (arg) => threads.spawn(arg) } } : {}
@@ -8219,6 +8301,7 @@ async function instantiate(host, module, memory, threads, {
8219
8301
  );
8220
8302
  const slicc = traced(stats, "slicc", host.sliccImports());
8221
8303
  const sliccFs = traced(stats, "slicc_fs", host.sliccFsImports());
8304
+ const sliccTty2 = traced(stats, "slicc_tty", host.sliccTtyImports());
8222
8305
  const hostImports = linkImports(
8223
8306
  module,
8224
8307
  preview1,
@@ -8228,7 +8311,8 @@ async function instantiate(host, module, memory, threads, {
8228
8311
  extra,
8229
8312
  foreign,
8230
8313
  slicc,
8231
- sliccFs
8314
+ sliccFs,
8315
+ sliccTty2
8232
8316
  );
8233
8317
  const imports = sync ? merge(hostImports, sync.linker.mainImports(module)) : hostImports;
8234
8318
  instance = await WebAssembly.instantiate(module, imports);
@@ -8435,7 +8519,7 @@ async function runWasiThread(init, port3) {
8435
8519
  throw e;
8436
8520
  }
8437
8521
  }
8438
- var TRAPPED, PREVIEW1, WASIX, SLICC, SIGNAL_CALLBACK, takeDefault, SLICC_FS, RESERVED2, importsSigactionHook, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
8522
+ var TRAPPED, PREVIEW1, WASIX, SLICC, SIGNAL_CALLBACK, takeDefault, SLICC_FS, SLICC_TTY, RESERVED2, importsSigactionHook, noErrno, FALLBACK_MAXIMUM_PAGES, LinkSync, DL_GEN, BACKTRACE_FRAMES;
8439
8523
  var init_wasi_runtime = __esm({
8440
8524
  "src/process/wasi/wasi-runtime.ts"() {
8441
8525
  "use strict";
@@ -8468,6 +8552,7 @@ var init_wasi_runtime = __esm({
8468
8552
  if (defaultAction(sig) === "terminate") throw new WasiExit(128 + sig);
8469
8553
  };
8470
8554
  SLICC_FS = "slicc_fs";
8555
+ SLICC_TTY = "slicc_tty";
8471
8556
  RESERVED2 = RESERVED_NAMESPACES;
8472
8557
  importsSigactionHook = (module) => WebAssembly.Module.imports(module).some((i) => i.module === SLICC && i.name === "sigaction_set");
8473
8558
  noErrno = (key) => `imports ${key}: its result cannot carry ENOSYS, and this host does not provide it`;
@@ -8916,6 +9001,56 @@ function latin1(bytes) {
8916
9001
  }
8917
9002
  return text;
8918
9003
  }
9004
+ function quoted(input, from) {
9005
+ let value2 = "";
9006
+ let at = from + 1;
9007
+ while (at < input.length) {
9008
+ const char = input[at++];
9009
+ if (char === '"') break;
9010
+ if (char !== "\\") value2 += char;
9011
+ else if (at < input.length) value2 += input[at++];
9012
+ else value2 += char;
9013
+ }
9014
+ return [value2, at];
9015
+ }
9016
+ function parameter(text, from, params) {
9017
+ let at = from + 1;
9018
+ while (SPACE.test(text[at] ?? "")) at++;
9019
+ let end = at;
9020
+ while (end < text.length && text[end] !== ";" && text[end] !== "=") end++;
9021
+ const name = text.slice(at, end).toLowerCase();
9022
+ if (text[end] !== "=") return end;
9023
+ const start2 = end + 1;
9024
+ let value2;
9025
+ if (text[start2] === '"') {
9026
+ [value2, at] = quoted(text, start2);
9027
+ end = text.indexOf(";", at);
9028
+ } else {
9029
+ end = text.indexOf(";", start2);
9030
+ value2 = text.slice(start2, end < 0 ? void 0 : end).replace(/[\t\n\r ]+$/, "");
9031
+ if (!value2) return end < 0 ? text.length : end;
9032
+ }
9033
+ if (end < 0) end = text.length;
9034
+ if (TOKEN.test(name) && QUOTABLE.test(value2) && !params.has(name)) {
9035
+ params.set(name, value2);
9036
+ }
9037
+ return end;
9038
+ }
9039
+ function mimeType(input) {
9040
+ const text = input.replace(/^[\t\n\r ]+|[\t\n\r ]+$/g, "");
9041
+ const slash = text.indexOf("/");
9042
+ const semi = text.indexOf(";", slash);
9043
+ const type = text.slice(0, slash);
9044
+ const subtype = text.slice(slash + 1, semi < 0 ? void 0 : semi).replace(/[\t\n\r ]+$/, "");
9045
+ if (slash < 0 || !TOKEN.test(type) || !TOKEN.test(subtype)) return void 0;
9046
+ const params = /* @__PURE__ */ new Map();
9047
+ for (let at = semi < 0 ? text.length : semi; at < text.length; ) at = parameter(text, at, params);
9048
+ let out = `${type}/${subtype}`.toLowerCase();
9049
+ for (const [name, value2] of params) {
9050
+ out += `;${name}=${TOKEN.test(value2) ? value2 : `"${value2.replace(/["\\]/g, "\\$&")}"`}`;
9051
+ }
9052
+ return out;
9053
+ }
8919
9054
  function dataResponse(request) {
8920
9055
  const url = withoutFragment(new URL(request.url));
8921
9056
  const rest2 = url.slice("data:".length);
@@ -8925,7 +9060,7 @@ function dataResponse(request) {
8925
9060
  let body = percentDecode(rest2.slice(comma + 1));
8926
9061
  const base642 = BASE64.exec(type);
8927
9062
  if (base642) {
8928
- type = type.slice(0, base642.index).replace(/[\t\n\f\r ]+$/, "");
9063
+ type = type.slice(0, base642.index);
8929
9064
  let binary;
8930
9065
  try {
8931
9066
  binary = atob(latin1(body));
@@ -8935,11 +9070,10 @@ function dataResponse(request) {
8935
9070
  body = Uint8Array.from(binary, (c) => c.charCodeAt(0));
8936
9071
  }
8937
9072
  if (type.startsWith(";")) type = `text/plain${type}`;
8938
- if (!MIME.test(type)) type = "text/plain;charset=US-ASCII";
8939
- const response = new Response(body, {
8940
- status: 200,
8941
- headers: { "content-type": type }
8942
- });
9073
+ const response = new Response(
9074
+ request.method === "HEAD" ? null : body,
9075
+ { status: 200, headers: { "content-type": mimeType(type) ?? "text/plain;charset=US-ASCII" } }
9076
+ );
8943
9077
  return withMeta(response, url, false);
8944
9078
  }
8945
9079
  function withMeta(response, url, redirected) {
@@ -9127,7 +9261,7 @@ function fetchOp(kernel) {
9127
9261
  }
9128
9262
  };
9129
9263
  }
9130
- var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, MIME, BASE64, SLICE;
9264
+ var CHUNK, MAX_REDIRECTS, NULL_BODY, REDIRECTS, BODY_HEADERS, DECODED, CREDENTIALS, OVER, TOKEN, QUOTABLE, SPACE, BASE64, SLICE;
9131
9265
  var init_js_fetch = __esm({
9132
9266
  "src/process/js/js-fetch.ts"() {
9133
9267
  "use strict";
@@ -9146,7 +9280,9 @@ var init_js_fetch = __esm({
9146
9280
  DECODED = /* @__PURE__ */ new Set(["gzip", "x-gzip", "deflate"]);
9147
9281
  CREDENTIALS = /* @__PURE__ */ new Set(["authorization", "proxy-authorization", "cookie", "cookie2"]);
9148
9282
  OVER = /* @__PURE__ */ Symbol("over");
9149
- MIME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+(?:[\t ]*;.*)?$/s;
9283
+ TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
9284
+ QUOTABLE = /^[\t\x20-\x7e\x80-\xff]*$/;
9285
+ SPACE = /[\t\n\r ]/;
9150
9286
  BASE64 = /; *base64$/i;
9151
9287
  SLICE = 32768;
9152
9288
  }
@@ -9623,6 +9759,7 @@ function rawOf(termios) {
9623
9759
  }
9624
9760
  function ttyOps(kernel) {
9625
9761
  const saved = /* @__PURE__ */ new Map();
9762
+ const terminalOf = async (fd) => (await kernel.json({ op: "fd-info", fd })).terminal ?? `fd ${fd}`;
9626
9763
  const getAttr = async (fd) => await kernel.json({ op: "tty-get", fd });
9627
9764
  const setAttr = async (fd, termios) => {
9628
9765
  await kernel.call({ op: "tty-set", fd, termios: copy(termios) });
@@ -9631,14 +9768,15 @@ function ttyOps(kernel) {
9631
9768
  getAttr,
9632
9769
  setAttr,
9633
9770
  async setRaw(fd, raw) {
9771
+ const terminal = await terminalOf(fd);
9634
9772
  if (!raw) {
9635
- const original = saved.get(fd);
9636
- saved.delete(fd);
9637
- if (original) await setAttr(fd, original);
9773
+ const original = saved.get(terminal);
9774
+ saved.delete(terminal);
9775
+ if (original) await setAttr(fd, original.termios);
9638
9776
  return;
9639
9777
  }
9640
9778
  const current = await getAttr(fd);
9641
- if (!saved.has(fd)) saved.set(fd, current);
9779
+ if (!saved.has(terminal)) saved.set(terminal, { fd, termios: current });
9642
9780
  await setAttr(fd, rawOf(current));
9643
9781
  },
9644
9782
  async size(fd) {
@@ -9651,9 +9789,9 @@ function ttyOps(kernel) {
9651
9789
  }
9652
9790
  };
9653
9791
  const restore = async () => {
9654
- for (const [fd, original] of [...saved].reverse()) {
9655
- saved.delete(fd);
9656
- await setAttr(fd, original).catch(() => void 0);
9792
+ for (const [terminal, { fd, termios }] of [...saved].reverse()) {
9793
+ saved.delete(terminal);
9794
+ await setAttr(fd, termios).catch(() => void 0);
9657
9795
  }
9658
9796
  };
9659
9797
  return { tty, restore };