@ai-ecoverse/slicc-kernel 1.43.1 → 1.45.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.
@@ -1465,7 +1465,7 @@ var init_sync_sab_wire = __esm({
1465
1465
  function createSyncSabTransport(sab, port2, deps = {}) {
1466
1466
  const views = sabViews(sab);
1467
1467
  const { header, window } = views;
1468
- const wait = deps.wait ?? ((a, i, v, t) => Atomics.wait(a, i, v, t));
1468
+ const wait2 = deps.wait ?? ((a, i, v, t) => Atomics.wait(a, i, v, t));
1469
1469
  const now = deps.now ?? (() => performance.now());
1470
1470
  let seq = 0;
1471
1471
  function awaitReady(id, deadline, label) {
@@ -1476,7 +1476,7 @@ function createSyncSabTransport(sab, port2, deps = {}) {
1476
1476
  }
1477
1477
  const remaining = deadline - now();
1478
1478
  if (remaining <= 0) throw syncError("ETIMEDOUT", label);
1479
- wait(header, SAB_I_PUB, published, remaining);
1479
+ wait2(header, SAB_I_PUB, published, remaining);
1480
1480
  }
1481
1481
  }
1482
1482
  return {
@@ -2896,6 +2896,9 @@ var init_process_fork = __esm({
2896
2896
  function status(r) {
2897
2897
  return r.ok ? 0 : -wasiErrno(r.errno);
2898
2898
  }
2899
+ function credOf(r) {
2900
+ return r.ok ? r.json : -wasiErrno(r.errno);
2901
+ }
2899
2902
  function number(r) {
2900
2903
  if (!r.ok) return -wasiErrno(r.errno);
2901
2904
  return r.kind === "json" && typeof r.json === "number" ? r.json : -wasiErrno("EIO");
@@ -3103,6 +3106,8 @@ function createProcessKernel(deps) {
3103
3106
  setsid: () => number(call2({ op: "proc-setsid" }, "setsid")),
3104
3107
  getpgid: (pid) => number(call2({ op: "proc-getpgid", pid }, "getpgid")),
3105
3108
  getsid: (pid) => number(call2({ op: "proc-getsid", pid }, "getsid")),
3109
+ cred: () => credOf(call2({ op: "proc-cred" }, "cred")),
3110
+ setcred: (change) => credOf(call2({ op: "proc-setcred", change }, "setcred")),
3106
3111
  tcgetpgrp(fd) {
3107
3112
  const kfd = Fs.getStream(fd)?.sliccKernelFd;
3108
3113
  if (kfd === void 0) return -wasiErrno("ENOTTY");
@@ -3436,6 +3441,25 @@ var init_process_sockets = __esm({
3436
3441
  }
3437
3442
  });
3438
3443
 
3444
+ // src/kernel/cred.ts
3445
+ var ROOT, MAX_GROUPS;
3446
+ var init_cred = __esm({
3447
+ "src/kernel/cred.ts"() {
3448
+ "use strict";
3449
+ init_types();
3450
+ ROOT = Object.freeze({
3451
+ ruid: 0,
3452
+ euid: 0,
3453
+ suid: 0,
3454
+ rgid: 0,
3455
+ egid: 0,
3456
+ sgid: 0,
3457
+ groups: [0]
3458
+ });
3459
+ MAX_GROUPS = 65536;
3460
+ }
3461
+ });
3462
+
3439
3463
  // src/process/procfs.ts
3440
3464
  function commOf(info) {
3441
3465
  const name = info.argv[0] ?? "";
@@ -3496,7 +3520,8 @@ function pidStat(info, boot) {
3496
3520
  }
3497
3521
  function pidStatus(info) {
3498
3522
  const state = info.state === "Z" ? "Z (zombie)" : "S (sleeping)";
3499
- const ids = `${UID} ${UID} ${UID} ${UID}`;
3523
+ const c = info.cred ?? ROOT;
3524
+ const ids = (r, e, s) => `${r} ${e} ${s} ${e}`;
3500
3525
  return [
3501
3526
  `Name: ${commOf(info)}`,
3502
3527
  `Umask: ${(info.umask ?? 18).toString(8).padStart(4, "0")}`,
@@ -3506,12 +3531,12 @@ function pidStatus(info) {
3506
3531
  `Pid: ${info.pid}`,
3507
3532
  `PPid: ${info.ppid}`,
3508
3533
  "TracerPid: 0",
3509
- `Uid: ${ids}`,
3510
- `Gid: ${ids}`,
3534
+ `Uid: ${ids(c.ruid, c.euid, c.suid)}`,
3535
+ `Gid: ${ids(c.rgid, c.egid, c.sgid)}`,
3511
3536
  "FDSize: 64",
3512
3537
  `VmSize: ${Math.ceil(info.memory / KIB)} kB`,
3513
3538
  `VmRSS: ${Math.ceil(info.memory / KIB)} kB`,
3514
- "Groups: ",
3539
+ `Groups: ${c.groups.join(" ")}`,
3515
3540
  `NSpid: ${info.pid}`,
3516
3541
  `NSpgid: ${info.pgid}`,
3517
3542
  `NSsid: ${info.sid}`,
@@ -3730,6 +3755,7 @@ var HZ, DIR_MODE2, FILE_MODE, LINK_MODE2, ENOENT, ESRCH, EINVAL, UID, KIB, FALLB
3730
3755
  var init_procfs = __esm({
3731
3756
  "src/process/procfs.ts"() {
3732
3757
  "use strict";
3758
+ init_cred();
3733
3759
  init_process_fds();
3734
3760
  HZ = 100;
3735
3761
  DIR_MODE2 = 16749;
@@ -4007,12 +4033,12 @@ async function runWasmProcess(init, port2, deps = {}) {
4007
4033
  const say = (fd) => (text) => sys.write(fd, encoder4.encode(`${text}
4008
4034
  `));
4009
4035
  let ready;
4010
- let failed2;
4036
+ let failed3;
4011
4037
  let memory;
4012
4038
  let exports;
4013
4039
  const initialized = new Promise((resolve, reject) => {
4014
4040
  ready = resolve;
4015
- failed2 = reject;
4041
+ failed3 = reject;
4016
4042
  });
4017
4043
  const id = identify(transport, init);
4018
4044
  const module = {
@@ -4065,7 +4091,7 @@ async function runWasmProcess(init, port2, deps = {}) {
4065
4091
  exports = instance.exports;
4066
4092
  publishMemory(init.sab, memory?.buffer.byteLength ?? 0);
4067
4093
  done(instance, init.program.module);
4068
- }, failed2);
4094
+ }, failed3);
4069
4095
  return {};
4070
4096
  },
4071
4097
  preRun: [
@@ -5453,10 +5479,11 @@ function wrap(table) {
5453
5479
  }
5454
5480
  return out;
5455
5481
  }
5456
- var WasiExit, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
5482
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW2, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, WasiHost;
5457
5483
  var init_wasi_host = __esm({
5458
5484
  "src/process/wasi/wasi-host.ts"() {
5459
5485
  "use strict";
5486
+ init_cred();
5460
5487
  init_wasi_abi();
5461
5488
  init_wasi_fds();
5462
5489
  init_wasi_files();
@@ -5469,6 +5496,7 @@ var init_wasi_host = __esm({
5469
5496
  this.code = code2;
5470
5497
  }
5471
5498
  };
5499
+ IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
5472
5500
  NS_PER_MS = 1000000n;
5473
5501
  AT_SYMLINK_NOFOLLOW2 = 1;
5474
5502
  DEFAULT_UMASK = 18;
@@ -5567,6 +5595,35 @@ var init_wasi_host = __esm({
5567
5595
  data: mem.string(dp, dl)
5568
5596
  }),
5569
5597
  umount2: (tp, tl, flags) => void this.o.kernel.call({ op: "umount", target: path(tp, tl), flags }),
5598
+ cred_get: (out) => {
5599
+ const cred = this.o.kernel.call({ op: "proc-cred" });
5600
+ const view = mem.view();
5601
+ view.getUint32(out + 20, true);
5602
+ IDS.forEach((key, i) => void view.setUint32(out + i * 4, cred[key], true));
5603
+ },
5604
+ cred_set: (...ids) => {
5605
+ const change = {};
5606
+ IDS.forEach((key, i) => {
5607
+ if (ids[i] !== -1) change[key] = ids[i] >>> 0;
5608
+ });
5609
+ void this.o.kernel.call({ op: "proc-setcred", change });
5610
+ },
5611
+ groups_get: (buf, cap, count) => {
5612
+ const { groups } = this.o.kernel.call({ op: "proc-cred" });
5613
+ if (cap !== 0 && cap < groups.length) throw new WasiError("EINVAL");
5614
+ const shown = cap === 0 ? [] : groups;
5615
+ const view = mem.view();
5616
+ view.getUint32(count, true);
5617
+ if (shown.length > 0) view.getUint32(buf + (shown.length - 1) * 4, true);
5618
+ shown.forEach((g, i) => void view.setUint32(buf + i * 4, g, true));
5619
+ view.setUint32(count, groups.length, true);
5620
+ },
5621
+ groups_set: (buf, n) => {
5622
+ if (n < 0 || n > MAX_GROUPS) throw new WasiError("EINVAL");
5623
+ const view = mem.view();
5624
+ const groups = Array.from({ length: n }, (_, i) => view.getUint32(buf + i * 4, true));
5625
+ void this.o.kernel.call({ op: "proc-setcred", change: { groups } });
5626
+ },
5570
5627
  sigaction_set: (sig, disposition, flags) => this.signals ? this.signals.disposition(sig, disposition, flags) : E.NOSYS
5571
5628
  });
5572
5629
  }
@@ -7691,7 +7748,7 @@ var init_wasix_host = __esm({
7691
7748
  }
7692
7749
  dlImports() {
7693
7750
  const { mem, host } = this;
7694
- const failed2 = (message2, buf, len) => {
7751
+ const failed3 = (message2, buf, len) => {
7695
7752
  if (len > 0) {
7696
7753
  const bytes = new TextEncoder().encode(message2).subarray(0, len - 1);
7697
7754
  mem.bytes(buf, bytes.length).set(bytes);
@@ -7700,12 +7757,12 @@ var init_wasix_host = __esm({
7700
7757
  return E.NOEXEC;
7701
7758
  };
7702
7759
  const linked = (buf, len, op, out) => {
7703
- if (!this.linker) return failed2("not a dynamically-linked program", buf, len);
7760
+ if (!this.linker) return failed3("not a dynamically-linked program", buf, len);
7704
7761
  try {
7705
7762
  out(op(this.linker));
7706
7763
  return E.SUCCESS;
7707
7764
  } catch (e) {
7708
- if (e instanceof DlError) return failed2(e.message, buf, len);
7765
+ if (e instanceof DlError) return failed3(e.message, buf, len);
7709
7766
  throw e;
7710
7767
  }
7711
7768
  };
@@ -8623,7 +8680,7 @@ function writable(io, fd) {
8623
8680
  });
8624
8681
  }
8625
8682
  function childOps(kernel, io, defaults) {
8626
- const wait = async (pid) => {
8683
+ const wait2 = async (pid) => {
8627
8684
  const r = await kernel.blocking({ op: "proc-wait", pid, nohang: false });
8628
8685
  const [, status2] = r.ok && r.kind === "json" ? r.json : [0, 0];
8629
8686
  return exitedOf(status2);
@@ -8638,7 +8695,7 @@ function childOps(kernel, io, defaults) {
8638
8695
  ...stdin !== void 0 ? { stdin: writable(io, stdin) } : {},
8639
8696
  ...stdout !== void 0 ? { stdout: readable(io, stdout) } : {},
8640
8697
  ...stderr !== void 0 ? { stderr: readable(io, stderr) } : {},
8641
- wait: () => wait(pid),
8698
+ wait: () => wait2(pid),
8642
8699
  kill: (signal) => kill(pid, signal)
8643
8700
  };
8644
8701
  };
@@ -8665,7 +8722,7 @@ function childOps(kernel, io, defaults) {
8665
8722
  await closeAll(io, theirs);
8666
8723
  }
8667
8724
  };
8668
- return { spawn, wait, kill };
8725
+ return { spawn, wait: wait2, kill };
8669
8726
  }
8670
8727
  async function closeAll(io, fds) {
8671
8728
  for (const fd of fds) if (fd !== void 0) await io.close(fd).catch(() => void 0);
@@ -8909,13 +8966,13 @@ function netOps(kernel, io) {
8909
8966
  const r = await kernel.raw({ op: "sock-connect", fd, addr, nonblock: true });
8910
8967
  if (!r.ok && r.errno !== "EINPROGRESS") throw new JsCallError(r.errno, "connect");
8911
8968
  await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
8912
- const failed2 = await kernel.json({
8969
+ const failed3 = await kernel.json({
8913
8970
  op: "sock-getopt",
8914
8971
  fd,
8915
8972
  level: SOL_SOCKET,
8916
8973
  name: SO_ERROR
8917
8974
  });
8918
- if (failed2 !== 0) throw new JsCallError(errnoName(failed2), "connect");
8975
+ if (failed3 !== 0) throw new JsCallError(errnoName(failed3), "connect");
8919
8976
  return connection(fd);
8920
8977
  });
8921
8978
  }
@@ -9159,6 +9216,156 @@ var init_js_sync = __esm({
9159
9216
  }
9160
9217
  });
9161
9218
 
9219
+ // src/process/js/js-websocket.ts
9220
+ function failed2(err) {
9221
+ return new TypeError("websocket failed", { cause: err });
9222
+ }
9223
+ function socketUrl(input) {
9224
+ const url = new URL(input);
9225
+ if (url.protocol === "http:") url.protocol = "ws:";
9226
+ else if (url.protocol === "https:") url.protocol = "wss:";
9227
+ if (url.protocol !== "ws:" && url.protocol !== "wss:") {
9228
+ throw new SyntaxError(`not a WebSocket URL: ${url.href}`);
9229
+ }
9230
+ url.hash = "";
9231
+ return url.href;
9232
+ }
9233
+ function closeCode(code2) {
9234
+ if (code2 === void 0) return 1e3;
9235
+ if (code2 === 1e3 || code2 >= 3e3 && code2 <= 4999) return code2;
9236
+ throw new JsCallError("EINVAL", `close code ${code2}`);
9237
+ }
9238
+ function closeReason(reason) {
9239
+ if (reason === void 0) return "";
9240
+ if (new TextEncoder().encode(reason).length > MAX_REASON) {
9241
+ throw new JsCallError("EINVAL", `close reason over ${MAX_REASON} bytes`);
9242
+ }
9243
+ return reason;
9244
+ }
9245
+ function websocketOp(kernel) {
9246
+ return async (input, options = {}) => {
9247
+ const url = socketUrl(input);
9248
+ const signal = options.signal ?? NEVER2;
9249
+ signal.throwIfAborted();
9250
+ const protocols = typeof options.protocols === "string" ? [options.protocols] : options.protocols ?? [];
9251
+ const handle = await kernel.json({
9252
+ op: "net-ws-open",
9253
+ url,
9254
+ protocols,
9255
+ headers: [...new Headers(options.headers)]
9256
+ });
9257
+ const free = () => kernel.raw({ op: "net-close", handle });
9258
+ let protocol;
9259
+ try {
9260
+ const r = await kernel.blocking({ op: "net-ws-ready", handle }, signal);
9261
+ protocol = (r.ok && r.kind === "json" ? r.json : {}).protocol;
9262
+ } catch (err) {
9263
+ await free();
9264
+ throw signal.aborted ? signal.reason : failed2(err);
9265
+ }
9266
+ let settle;
9267
+ let lose;
9268
+ const closed = new Promise((resolve, reject) => {
9269
+ settle = resolve;
9270
+ lose = reject;
9271
+ });
9272
+ closed.catch(() => void 0);
9273
+ const stop = new AbortController();
9274
+ let freed = false;
9275
+ const onAbort = () => hardStop(signal.reason);
9276
+ const finish = () => {
9277
+ freed = true;
9278
+ signal.removeEventListener("abort", onAbort);
9279
+ void free();
9280
+ };
9281
+ const hardStop = (reason) => {
9282
+ if (stop.signal.aborted) return;
9283
+ stop.abort(reason);
9284
+ lose(reason);
9285
+ finish();
9286
+ };
9287
+ signal.addEventListener("abort", onAbort, { once: true });
9288
+ let settled = false;
9289
+ let readDone = false;
9290
+ const release = () => {
9291
+ if (!settled || !readDone || freed) return;
9292
+ finish();
9293
+ };
9294
+ kernel.blocking({ op: "net-ws-wait", handle }, stop.signal).then((r) => {
9295
+ settled = true;
9296
+ settle(r.json);
9297
+ release();
9298
+ }).catch(lose);
9299
+ const close = (how = {}) => {
9300
+ void kernel.raw({
9301
+ op: "net-ws-close",
9302
+ handle,
9303
+ code: closeCode(how.code),
9304
+ reason: closeReason(how.reason)
9305
+ });
9306
+ };
9307
+ const readable2 = new ReadableStream(
9308
+ {
9309
+ async pull(controller) {
9310
+ let r;
9311
+ try {
9312
+ r = await kernel.blocking({ op: "net-ws-recv", handle }, stop.signal);
9313
+ } catch (err) {
9314
+ hardStop(stop.signal.aborted ? stop.signal.reason : failed2(err));
9315
+ throw stop.signal.reason;
9316
+ }
9317
+ stop.signal.throwIfAborted();
9318
+ if (r.ok && r.kind === "bytes") {
9319
+ controller.enqueue(r.bytes);
9320
+ return;
9321
+ }
9322
+ const text = (r.ok && r.kind === "json" ? r.json : {}).text;
9323
+ if (text !== void 0) {
9324
+ controller.enqueue(text);
9325
+ return;
9326
+ }
9327
+ controller.close();
9328
+ readDone = true;
9329
+ release();
9330
+ },
9331
+ cancel: () => {
9332
+ close();
9333
+ readDone = true;
9334
+ release();
9335
+ }
9336
+ },
9337
+ { highWaterMark: 0 }
9338
+ );
9339
+ const writable2 = new WritableStream({
9340
+ async write(chunk, controller) {
9341
+ stop.signal.throwIfAborted();
9342
+ const body = typeof chunk === "string" ? { text: chunk } : { body: chunk };
9343
+ let buffered = await kernel.json({ op: "net-ws-send", handle, ...body });
9344
+ while (buffered > SEND_BUFFER) {
9345
+ await wait(10);
9346
+ stop.signal.throwIfAborted();
9347
+ controller.signal.throwIfAborted();
9348
+ buffered = await kernel.json({ op: "net-ws-send", handle });
9349
+ }
9350
+ },
9351
+ close: () => close(),
9352
+ abort: () => close({ code: 1e3, reason: "" })
9353
+ });
9354
+ return { url, protocol, readable: readable2, writable: writable2, closed, close };
9355
+ };
9356
+ }
9357
+ var SEND_BUFFER, MAX_REASON, NEVER2, wait;
9358
+ var init_js_websocket = __esm({
9359
+ "src/process/js/js-websocket.ts"() {
9360
+ "use strict";
9361
+ init_js_kernel();
9362
+ SEND_BUFFER = 1024 * 1024;
9363
+ MAX_REASON = 123;
9364
+ NEVER2 = new AbortController().signal;
9365
+ wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
9366
+ }
9367
+ });
9368
+
9162
9369
  // src/process/js/js-context.ts
9163
9370
  function identityOf(answer2, fallback) {
9164
9371
  const id = answer2;
@@ -9324,6 +9531,7 @@ function createContext(o) {
9324
9531
  sync,
9325
9532
  ...children,
9326
9533
  net: netOps(kernel, io),
9534
+ websocket: websocketOp(kernel),
9327
9535
  exit
9328
9536
  };
9329
9537
  const drain2 = async () => {
@@ -9461,6 +9669,7 @@ var init_js_context = __esm({
9461
9669
  init_js_kernel();
9462
9670
  init_js_net();
9463
9671
  init_js_sync();
9672
+ init_js_websocket();
9464
9673
  JsExit = class extends Error {
9465
9674
  status;
9466
9675
  constructor(status2) {
@@ -9657,20 +9866,20 @@ function started(init, port2, run, wasi, js) {
9657
9866
  return run(wasmInit, port2);
9658
9867
  }
9659
9868
  function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs) {
9660
- const failed2 = (err) => port2.postMessage({
9869
+ const failed3 = (err) => port2.postMessage({
9661
9870
  type: WASM_PROCESS_ERROR,
9662
9871
  message: err instanceof Error ? err.stack ?? err.message : String(err)
9663
9872
  });
9664
9873
  return (data) => {
9665
9874
  const type = data?.type;
9666
9875
  if (type === WASM_THREAD_INIT) {
9667
- wasi().then((m) => m.runWasiThread(data, port2)).catch(failed2);
9876
+ wasi().then((m) => m.runWasiThread(data, port2)).catch(failed3);
9668
9877
  return;
9669
9878
  }
9670
9879
  if (type !== WASM_PROCESS_INIT) return;
9671
9880
  started(data, port2, run, wasi, js).then(
9672
9881
  (code2) => port2.postMessage({ type: WASM_PROCESS_EXIT, code: code2 }),
9673
- failed2
9882
+ failed3
9674
9883
  );
9675
9884
  };
9676
9885
  }