@ai-ecoverse/slicc-kernel 1.95.3 → 1.96.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.
@@ -1568,6 +1568,7 @@ function entryOf(info) {
1568
1568
  return {
1569
1569
  type: "kernel",
1570
1570
  kind: info.kind,
1571
+ dgram: info.dgram === true,
1571
1572
  nonblock: ((info.flags ?? 0) & O_NONBLOCK) !== 0,
1572
1573
  append: ((info.flags ?? 0) & O_APPEND) !== 0
1573
1574
  };
@@ -1782,8 +1783,8 @@ var init_wasi_fds = __esm({
1782
1783
  sockets() {
1783
1784
  return [...this.table].filter(([, e]) => e.type === "kernel" && e.kind === "socket").map(([fd]) => fd).sort((a, b) => a - b);
1784
1785
  }
1785
- adopt(fd, kind, nonblock) {
1786
- this.table.set(fd, { type: "kernel", kind, nonblock, append: false });
1786
+ adopt(fd, kind, nonblock, dgram = false) {
1787
+ this.table.set(fd, { type: "kernel", kind, dgram, nonblock, append: false });
1787
1788
  if (this.shared && nonblock) this.publishFlags(fd, { nonblock, append: false });
1788
1789
  this.bump();
1789
1790
  }
@@ -2005,9 +2006,17 @@ var init_wasi_fds = __esm({
2005
2006
  if (!e.kind) {
2006
2007
  const info = this.kernel.call({ op: "fd-info", fd });
2007
2008
  e.kind = info.kind ?? (info.tty ? "tty" : "stream");
2009
+ e.dgram = info.dgram === true;
2008
2010
  }
2009
2011
  return e.kind;
2010
2012
  }
2013
+ datagram(fd, e) {
2014
+ if (this.kind(fd, e) !== "socket") return false;
2015
+ if (e.dgram === void 0) {
2016
+ e.dgram = this.kernel.call({ op: "fd-info", fd }).dgram === true;
2017
+ }
2018
+ return e.dgram;
2019
+ }
2011
2020
  flushAll() {
2012
2021
  for (const buffer of this.buffers.values()) {
2013
2022
  try {
@@ -2559,299 +2568,702 @@ var init_wasi_termios = __esm({
2559
2568
  }
2560
2569
  });
2561
2570
 
2562
- // src/process/wasi/wasi-host.ts
2563
- function idOf(value2) {
2564
- return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
2571
+ // src/kernel/net/datagram-wire.ts
2572
+ function decodeReceived(raw) {
2573
+ const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
2574
+ const length = view.getUint8(3);
2575
+ return {
2576
+ truncated: (view.getUint8(0) & 1) !== 0,
2577
+ port: view.getUint16(1),
2578
+ host: new TextDecoder().decode(raw.subarray(4, 4 + length)),
2579
+ bytes: raw.subarray(4 + length)
2580
+ };
2565
2581
  }
2566
- function linkedOf(st) {
2567
- return (st.nlink ?? 1) > 1 ? st : void 0;
2582
+ var init_datagram_wire = __esm({
2583
+ "src/kernel/net/datagram-wire.ts"() {
2584
+ "use strict";
2585
+ }
2586
+ });
2587
+
2588
+ // src/kernel/net/loopback-names.ts
2589
+ function isKernelLoopbackHost(hostname) {
2590
+ const host = hostname.replace(/^\[(.*)\]$/, "$1").replace(/\.$/, "").toLowerCase();
2591
+ return host === "localhost" || host.endsWith(".localhost") || host === "0.0.0.0" || LOOPBACK_V4.test(host) || LOOPBACK_V6.has(host) || MAPPED_V4.test(host);
2568
2592
  }
2569
- function linkedElsewhere(fs, path) {
2593
+ function reserved(name2) {
2594
+ const lower = name2.toLowerCase();
2595
+ return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
2596
+ }
2597
+ function isHostname(name2) {
2598
+ if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
2599
+ return name2.split(".").every((l) => LABEL.test(l));
2600
+ }
2601
+ function hostnameOf(env) {
2602
+ return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;
2603
+ }
2604
+ function ownNames(hostname) {
2605
+ return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
2606
+ }
2607
+ function hostsFile(hostname = DEFAULT_HOSTNAME) {
2608
+ return [
2609
+ "127.0.0.1 localhost localhost.localdomain",
2610
+ "::1 localhost ip6-localhost",
2611
+ `${HOSTNAME_ADDRESS} ${ownNames(hostname).join(" ")}`,
2612
+ `${HOST_LOOPBACK_ADDRESS.join(".")} ${HOST_LOOPBACK}`,
2613
+ ""
2614
+ ].join("\n");
2615
+ }
2616
+ var HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS, PAGE_LOOPBACK, PAGE_LOOPBACK_URL, LOOPBACK_V4, LOOPBACK_V6, MAPPED_V4, DEFAULT_HOSTNAME, HOSTNAME_ADDRESS, LIBC_HOSTNAMES, LABEL;
2617
+ var init_loopback_names = __esm({
2618
+ "src/kernel/net/loopback-names.ts"() {
2619
+ "use strict";
2620
+ HOST_LOOPBACK = "host.slicc.internal";
2621
+ HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
2622
+ PAGE_LOOPBACK = "kernel.localhost";
2623
+ PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
2624
+ LOOPBACK_V4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
2625
+ LOOPBACK_V6 = /* @__PURE__ */ new Set(["::1", "::", "0:0:0:0:0:0:0:1"]);
2626
+ MAPPED_V4 = /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/;
2627
+ DEFAULT_HOSTNAME = "slicc";
2628
+ HOSTNAME_ADDRESS = "127.0.1.1";
2629
+ LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
2630
+ LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
2631
+ }
2632
+ });
2633
+
2634
+ // src/kernel/net/routes.ts
2635
+ function ipv4Bytes(text) {
2636
+ const parts = text.split(".");
2637
+ if (parts.length !== 4 || !parts.every((p) => /^\d{1,3}$/.test(p))) return void 0;
2638
+ const bytes = parts.map(Number);
2639
+ return bytes.every((b) => b <= 255) ? bytes : void 0;
2640
+ }
2641
+ function ipv6Groups(text) {
2642
+ if (!text.includes(":")) return void 0;
2643
+ let canonical;
2570
2644
  try {
2571
- return linkedOf(fs.lstat(path));
2645
+ canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
2572
2646
  } catch {
2573
2647
  return void 0;
2574
2648
  }
2649
+ const [head, tail] = canonical.split("::");
2650
+ const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
2651
+ const front = part(head);
2652
+ const back = part(tail);
2653
+ return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
2575
2654
  }
2576
- function filetypeOf(s) {
2577
- if (!s) return FILETYPE.UNKNOWN;
2578
- if (s.isSymbolicLink) return FILETYPE.SYMBOLIC_LINK;
2579
- if (s.isDirectory) return FILETYPE.DIRECTORY;
2580
- return s.isFile ? FILETYPE.REGULAR_FILE : FILETYPE.UNKNOWN;
2655
+ function toBits(values, width) {
2656
+ return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
2581
2657
  }
2582
- function filestatOf(path, s) {
2583
- return {
2584
- filetype: filetypeOf(s),
2585
- size: BigInt(s.size),
2586
- ino: s.ino !== void 0 ? BigInt(s.ino) : pathInode(path),
2587
- ...s.nlink !== void 0 ? { nlink: BigInt(s.nlink) } : {},
2588
- mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) * NS_PER_MS
2589
- };
2658
+ function addressBits(host) {
2659
+ const v4 = ipv4Bytes(host);
2660
+ if (v4) return { v6: false, bits: toBits(v4, 8) };
2661
+ const v6 = ipv6Groups(host);
2662
+ return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
2590
2663
  }
2591
- function kernelFiletype(kind) {
2592
- switch (kind) {
2593
- case "tty":
2594
- case "sealed":
2595
- case "clipboard":
2596
- return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
2597
- case "device":
2598
- return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
2599
- case "socket":
2600
- return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
2601
- case "file":
2602
- return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
2603
- default:
2604
- return { filetype: FILETYPE.UNKNOWN, seeks: false };
2664
+ function parsePrefix(text) {
2665
+ const parts = text.trim().split("/");
2666
+ if (parts.length > 2) return void 0;
2667
+ const [address = "", size] = parts;
2668
+ const parsed = addressBits(address);
2669
+ if (!parsed) return void 0;
2670
+ const max = parsed.v6 ? 128 : 32;
2671
+ const length = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
2672
+ if (length < 0 || length > max) return void 0;
2673
+ return { ...parsed, length };
2674
+ }
2675
+ var HOST_ADDRESS, RESERVED;
2676
+ var init_routes = __esm({
2677
+ "src/kernel/net/routes.ts"() {
2678
+ "use strict";
2679
+ init_loopback_names();
2680
+ HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
2681
+ RESERVED = [
2682
+ "0.0.0.0/8",
2683
+ "127.0.0.0/8",
2684
+ "169.254.0.0/16",
2685
+ "224.0.0.0/4",
2686
+ "240.0.0.0/4",
2687
+ "::/96",
2688
+ "::ffff:0:0/96",
2689
+ "fe80::/10",
2690
+ "ff00::/8"
2691
+ ].map((p) => parsePrefix(p));
2692
+ }
2693
+ });
2694
+
2695
+ // src/process/wasi/wasix-sockets.ts
2696
+ function readAddr(view, ptr) {
2697
+ const tag = view.getUint8(ptr);
2698
+ if (tag === UNIX) {
2699
+ let end = ptr + 2;
2700
+ while (end < ptr + 110 && view.getUint8(end) !== 0) end++;
2701
+ const path = new TextDecoder().decode(
2702
+ new Uint8Array(view.buffer, ptr + 2, end - ptr - 2).slice()
2703
+ );
2704
+ return { family: "unix", path };
2705
+ }
2706
+ const port3 = view.getUint16(ptr + 2, true);
2707
+ if (tag === INET4) {
2708
+ const host = [0, 1, 2, 3].map((i) => view.getUint8(ptr + 4 + i)).join(".");
2709
+ return { family: "inet", host, port: port3 };
2605
2710
  }
2711
+ if (tag === INET6) {
2712
+ return { family: "inet", host: ipv6Host(new Uint8Array(view.buffer, ptr + 4, 16)), port: port3 };
2713
+ }
2714
+ throw new WasiError("EAFNOSUPPORT");
2606
2715
  }
2607
- function direntRecord(next2, ino, name2, filetype) {
2608
- const nameBytes = new TextEncoder().encode(name2);
2609
- const record = new Uint8Array(SIZE.DIRENT + nameBytes.length);
2610
- const v = new DataView(record.buffer);
2611
- v.setBigUint64(0, BigInt(next2), true);
2612
- v.setBigUint64(8, ino, true);
2613
- v.setUint32(16, nameBytes.length, true);
2614
- v.setUint8(20, filetype);
2615
- record.set(nameBytes, SIZE.DIRENT);
2616
- return record;
2716
+ function ipv6Host(bytes) {
2717
+ const zeros = (n) => bytes.subarray(0, n).every((b) => b === 0);
2718
+ if (zeros(16)) return "0.0.0.0";
2719
+ if (zeros(15) && bytes[15] === 1) return LOOPBACK;
2720
+ if (zeros(10) && bytes[10] === 255 && bytes[11] === 255) return bytes.subarray(12).join(".");
2721
+ const groups = [0, 2, 4, 6, 8, 10, 12, 14].map(
2722
+ (i) => (bytes[i] << 8 | bytes[i + 1]).toString(16)
2723
+ );
2724
+ return new URL(`http://[${groups.join(":")}]/`).hostname.slice(1, -1);
2617
2725
  }
2618
- function wrap(table) {
2619
- const out = {};
2620
- for (const [name2, fn] of Object.entries(table)) {
2621
- out[name2] = (...args) => {
2622
- try {
2623
- return fn(...args) ?? E.SUCCESS;
2624
- } catch (e) {
2625
- if (e instanceof WasiExit) throw e;
2626
- if (e instanceof WasiError) return wasiErrnoOf(e.code);
2627
- const code2 = e?.code;
2628
- if (typeof code2 === "string") return wasiErrnoOf(code2);
2629
- if (e instanceof RangeError) return E.FAULT;
2630
- throw e;
2631
- }
2632
- };
2726
+ function writeAddr(view, ptr, addr) {
2727
+ new Uint8Array(view.buffer, ptr, 110).fill(0);
2728
+ if (!addr) return;
2729
+ if (addr.family === "unix") {
2730
+ view.setUint8(ptr, UNIX);
2731
+ new Uint8Array(view.buffer, ptr + 2, 107).set(
2732
+ new TextEncoder().encode(addr.path).subarray(0, 107)
2733
+ );
2734
+ return;
2633
2735
  }
2634
- return out;
2736
+ view.setUint16(ptr + 2, addr.port, true);
2737
+ const groups = ipv4(addr.host) ? void 0 : ipv6Groups(addr.host);
2738
+ if (groups) {
2739
+ view.setUint8(ptr, INET6);
2740
+ groups.forEach((g, i) => void view.setUint16(ptr + 4 + i * 2, g));
2741
+ return;
2742
+ }
2743
+ view.setUint8(ptr, INET4);
2744
+ const octets = ipv4(addr.host) ?? [127, 0, 0, 1];
2745
+ octets.forEach((b, i) => void view.setUint8(ptr + 4 + i, b));
2635
2746
  }
2636
- var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW, AT_EACCESS, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SIG_IGN, SEALED_MODE, WasiHost;
2637
- var init_wasi_host = __esm({
2638
- "src/process/wasi/wasi-host.ts"() {
2639
- "use strict";
2640
- init_dev_removal();
2641
- init_physical_path();
2642
- init_cpu_clock();
2643
- init_cred();
2644
- init_wasi_abi();
2645
- init_wasi_fds();
2646
- init_wasi_files();
2647
- init_wasi_memory();
2648
- init_wasi_poll();
2649
- init_wasi_termios();
2650
- WasiExit = class extends Error {
2651
- code;
2652
- constructor(code2) {
2653
- super(`exit ${code2}`);
2654
- this.code = code2;
2655
- }
2656
- };
2657
- IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
2658
- NS_PER_MS = 1000000n;
2659
- AT_SYMLINK_NOFOLLOW = 1;
2660
- AT_EACCESS = 2;
2661
- ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
2662
- GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
2663
- S_IFIFO = 4096;
2664
- DEFAULT_UMASK = 18;
2665
- MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
2666
- MAX_READ = 1024 * 1024;
2667
- SIGPIPE_EXIT = 141;
2668
- SIG_IGN = 1;
2669
- SEALED_MODE = 8630;
2670
- WasiHost = class {
2671
- mem = new WasiMemory();
2672
- fds;
2673
- started = performance.now();
2674
- cache;
2675
- startCwd;
2676
- interruptWakes = false;
2677
- entered = false;
2678
- onRaise;
2679
- muted;
2680
- signals;
2681
- sigmask;
2682
- linkedTls;
2683
- linkedModules;
2684
- interrupted;
2685
- quietly = (fn) => fn();
2686
- listening;
2687
- o;
2688
- constructor(o) {
2689
- const { kernel } = o;
2690
- const call2 = (req) => {
2691
- if (req.op !== "fd-promote") this.fds.flushEarly();
2692
- return kernel.call(req);
2693
- };
2694
- const sys = new Proxy(kernel.sys, {
2695
- get: (target, name2) => {
2696
- const member = Reflect.get(target, name2);
2697
- if (typeof member !== "function") return member;
2698
- return (...args) => {
2699
- this.fds.flushEarly();
2700
- return member.apply(target, args);
2701
- };
2702
- }
2703
- });
2704
- this.o = { ...o, kernel: { sys, call: call2 } };
2705
- this.startCwd = o.cwd;
2706
- this.fds = new WasiFds(this.o.kernel, o.fs);
2707
- if (o.shared) this.fds.share(o.shared, true);
2708
- else if (o.forked) this.fds.restore(o.forked.fds, o.forked.cloexec);
2709
- else this.fds.setup(o.cwd, o.inherited ?? [], o.preopenRoot === true);
2710
- this.listening = o.shared ? [] : this.fds.sockets();
2711
- }
2712
- get cwd() {
2713
- return this.fds.cwd() ?? this.startCwd;
2714
- }
2715
- created(path, mode) {
2716
- const umask = this.o.kernel.call({ op: "proc-umask" });
2717
- if (umask !== DEFAULT_UMASK) this.o.fs.chmod(path, mode & ~umask);
2747
+ function ipBytes(host) {
2748
+ const groups = ipv4(host) ? void 0 : ipv6Groups(host);
2749
+ return groups ? groups.flatMap((g) => [g >> 8, g & 255]) : ipv4(host);
2750
+ }
2751
+ function ipv4(host) {
2752
+ const parts = host.split(".");
2753
+ if (parts.length !== 4) return void 0;
2754
+ const bytes = parts.map((p) => /^\d{1,3}$/.test(p) ? Number(p) : Number.NaN);
2755
+ return bytes.every((b) => b >= 0 && b <= 255) ? bytes : void 0;
2756
+ }
2757
+ function openRequest(af, type) {
2758
+ if (af !== INET4 && af !== INET6 && af !== UNIX) throw new WasiError("EAFNOSUPPORT");
2759
+ if (type !== STREAM && (type !== DGRAM || af === UNIX)) throw new WasiError("EPROTONOSUPPORT");
2760
+ const domain = af === UNIX ? "unix" : "inet";
2761
+ return {
2762
+ op: "sock-open",
2763
+ domain,
2764
+ ...type === DGRAM ? { type: "dgram" } : {}
2765
+ };
2766
+ }
2767
+ function optionalAddr(view, ptr) {
2768
+ if (ptr === 0 || view.getUint8(ptr) === 0) return void 0;
2769
+ return readAddr(view, ptr);
2770
+ }
2771
+ function datagramCalls(host) {
2772
+ const { mem, o } = host;
2773
+ const call2 = (req) => o.kernel.call(req);
2774
+ return {
2775
+ recvFrom(fd, nonblock, iovs, n, riflags, outLen, outFlags, outAddr) {
2776
+ const max = Math.min(mem.capacity(iovs, n), MAX_DATAGRAM);
2777
+ const peek = (riflags & RIFLAG_PEEK) !== 0;
2778
+ const raw = call2({ op: "sock-recvfrom", fd, max, peek, nonblock });
2779
+ const got = decodeReceived(raw);
2780
+ const view = mem.view();
2781
+ view.setUint32(outLen, mem.scatter(iovs, n, got.bytes), true);
2782
+ view.setUint16(outFlags, got.truncated ? RECV_DATA_TRUNCATED : 0, true);
2783
+ if (outAddr)
2784
+ writeAddr(mem.view(), outAddr, { family: "inet", host: got.host, port: got.port });
2785
+ return E.SUCCESS;
2786
+ },
2787
+ sendTo(fd, nonblock, iovs, n, addr, out) {
2788
+ const to = optionalAddr(mem.view(), addr);
2789
+ const body = mem.gather(iovs, n);
2790
+ const sent = call2({ op: "sock-sendto", fd, body, ...to ? { addr: to } : {}, nonblock });
2791
+ mem.view().setUint32(out, sent, true);
2792
+ return E.SUCCESS;
2793
+ }
2794
+ };
2795
+ }
2796
+ function wasixSocketImports(host, preview1) {
2797
+ const { mem, fds, o } = host;
2798
+ const call2 = (req) => o.kernel.call(req);
2799
+ const socket = (fd) => {
2800
+ const e = fds.get(fd);
2801
+ if (e.type !== "kernel" || fds.kind(fd, e) !== "socket") throw new WasiError("ENOTSOCK");
2802
+ return e;
2803
+ };
2804
+ const option = (opt) => OPTIONS[opt];
2805
+ const datagrams = (fd) => {
2806
+ try {
2807
+ const e = fds.get(fd);
2808
+ return e.type === "kernel" && fds.datagram(fd, e);
2809
+ } catch {
2810
+ return false;
2811
+ }
2812
+ };
2813
+ const dgram = datagramCalls(host);
2814
+ return {
2815
+ sock_open: (af, type, _proto, out) => {
2816
+ const req = openRequest(af, type);
2817
+ const fd = call2(req);
2818
+ fds.adopt(fd, "socket", false, "type" in req);
2819
+ mem.view().setUint32(out, fd, true);
2820
+ },
2821
+ sock_pair: (af, type, _proto, out1, out2) => {
2822
+ if (af !== UNIX)
2823
+ throw new WasiError(af === INET4 || af === INET6 ? "EOPNOTSUPP" : "EAFNOSUPPORT");
2824
+ if (type !== STREAM) throw new WasiError("EPROTONOSUPPORT");
2825
+ mem.view().setUint32(out1, 0, true);
2826
+ mem.view().setUint32(out2, 0, true);
2827
+ const [a, b] = call2({ op: "sock-pair", domain: "unix" });
2828
+ fds.adopt(a, "socket", false);
2829
+ fds.adopt(b, "socket", false);
2830
+ mem.view().setUint32(out1, a, true);
2831
+ mem.view().setUint32(out2, b, true);
2832
+ },
2833
+ sock_bind: (fd, addr) => {
2834
+ socket(fd);
2835
+ call2({ op: "sock-bind", fd, addr: readAddr(mem.view(), addr) });
2836
+ },
2837
+ sock_listen: (fd, backlog) => {
2838
+ socket(fd);
2839
+ call2({ op: "sock-listen", fd, backlog });
2840
+ },
2841
+ sock_connect: (fd, addr) => {
2842
+ const e = socket(fd);
2843
+ call2({ op: "sock-connect", fd, addr: readAddr(mem.view(), addr), nonblock: e.nonblock });
2844
+ },
2845
+ sock_accept_v2: (fd, flags, outFd, outAddr) => {
2846
+ const e = socket(fd);
2847
+ const r = call2({ op: "sock-accept", fd, nonblock: e.nonblock });
2848
+ fds.adopt(r.fd, "socket", (flags & FDFLAGS.NONBLOCK) !== 0);
2849
+ mem.view().setUint32(outFd, r.fd, true);
2850
+ writeAddr(mem.view(), outAddr, r.peer);
2851
+ },
2852
+ sock_addr_local: (fd, out) => {
2853
+ socket(fd);
2854
+ writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: false }));
2855
+ },
2856
+ sock_addr_peer: (fd, out) => {
2857
+ socket(fd);
2858
+ writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: true }));
2859
+ },
2860
+ sock_recv_from: (fd, iovs, n, riflags, outLen, outFlags, outAddr) => {
2861
+ if (datagrams(fd)) {
2862
+ const e = socket(fd);
2863
+ return dgram.recvFrom(fd, e.nonblock, iovs, n, riflags, outLen, outFlags, outAddr);
2718
2864
  }
2719
- sliccTtyImports() {
2720
- return wrap(sliccTty(this.mem, this.fds, this.o.kernel, () => this.interrupted?.()));
2865
+ const r = preview1.sock_recv(
2866
+ fd,
2867
+ iovs,
2868
+ n,
2869
+ riflags,
2870
+ outLen,
2871
+ outFlags
2872
+ );
2873
+ if (r !== E.SUCCESS) return r;
2874
+ writeAddr(mem.view(), outAddr, call2({ op: "sock-name", fd, peer: true }));
2875
+ return E.SUCCESS;
2876
+ },
2877
+ sock_send_to: (fd, iovs, n, flags, addr, out) => {
2878
+ if (datagrams(fd)) return dgram.sendTo(fd, socket(fd).nonblock, iovs, n, addr, out);
2879
+ return preview1.sock_send(
2880
+ fd,
2881
+ iovs,
2882
+ n,
2883
+ flags,
2884
+ out
2885
+ );
2886
+ },
2887
+ sock_status: (fd, out) => {
2888
+ socket(fd);
2889
+ mem.view().setUint8(out, 1);
2890
+ },
2891
+ sock_get_opt_flag: (fd, opt, out) => {
2892
+ socket(fd);
2893
+ const pair = option(opt);
2894
+ const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
2895
+ mem.view().setUint8(out, v ? 1 : 0);
2896
+ },
2897
+ sock_set_opt_flag: (fd, opt, flag) => {
2898
+ socket(fd);
2899
+ const pair = option(opt);
2900
+ if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: flag ? 1 : 0 });
2901
+ },
2902
+ sock_get_opt_size: (fd, opt, out) => {
2903
+ socket(fd);
2904
+ const pair = option(opt);
2905
+ const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
2906
+ mem.view().setBigUint64(out, BigInt(v), true);
2907
+ },
2908
+ sock_set_opt_size: (fd, opt, size) => {
2909
+ socket(fd);
2910
+ const pair = option(opt);
2911
+ if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: Number(size) });
2912
+ },
2913
+ sock_get_opt_time: (fd, _opt, out) => {
2914
+ socket(fd);
2915
+ new Uint8Array(mem.view().buffer, out, 16).fill(0);
2916
+ },
2917
+ sock_set_opt_time: (fd) => void socket(fd),
2918
+ sock_send_file: () => E.NOSYS,
2919
+ resolve: (name2, len, _port, addrs, naddrs, out) => {
2920
+ const found = call2({ op: "sock-resolve", name: mem.string(name2, len), family: 0 });
2921
+ const ips = found.map(ipBytes).filter((ip) => ip !== void 0);
2922
+ if (ips.length === 0) throw new WasiError("ENOENT");
2923
+ if (naddrs < 1) throw new WasiError("EINVAL");
2924
+ const view = mem.view();
2925
+ const count = Math.min(ips.length, naddrs);
2926
+ new Uint8Array(view.buffer, addrs, ADDR_IP_SIZE * count).fill(0);
2927
+ for (let i = 0; i < count; i++) {
2928
+ const at = addrs + i * ADDR_IP_SIZE;
2929
+ view.setUint8(at, ips[i].length === 4 ? INET4 : INET6);
2930
+ new Uint8Array(view.buffer, at + 2, ips[i].length).set(ips[i]);
2721
2931
  }
2722
- sliccFsImports() {
2723
- const { mem, fds } = this;
2724
- const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
2725
- const pathOf = (fd) => {
2726
- const e = fds.get(fd);
2727
- if (e.type === "dir") return e.path;
2728
- if (e.type === "file") return e.file.path;
2729
- const path = e.type === "kernel" && fds.kind(fd, e) === "file" ? this.kernelStat(fd).path : void 0;
2730
- if (path === void 0) throw new WasiError("EBADF");
2731
- return path;
2732
- };
2733
- const target = (path, flags) => {
2734
- if (flags & AT_SYMLINK_NOFOLLOW && this.o.fs.lstat(path).isSymbolicLink) {
2735
- throw new WasiError("ENOTSUP");
2736
- }
2737
- return path;
2738
- };
2739
- const modeOf2 = (st) => (st.mode ?? 0) & 4095;
2740
- const chown = (path, uid, gid, follow2, handle) => {
2741
- const { chown: own } = this.o.fs;
2742
- if (!own) throw new WasiError("ENOSYS");
2743
- own.call(this.o.fs, path, idOf(uid), idOf(gid), follow2, handle);
2744
- };
2745
- const caller = () => {
2746
- const cred = this.o.kernel.call({ op: "proc-cred" });
2747
- return [cred.euid, cred.egid];
2748
- };
2749
- const owner = (st, out) => {
2750
- const [uid, gid] = st?.uid === void 0 ? caller() : [st.uid, st.gid];
2751
- const view = mem.view();
2752
- view.getUint32(out + 4, true);
2753
- view.setUint32(out, uid, true);
2754
- view.setUint32(out + 4, gid, true);
2755
- };
2756
- const fdOwned = (fd) => {
2757
- const e = fds.get(fd);
2758
- if (e.type === "device") return ROOT_IDS;
2759
- const kind = e.type === "kernel" ? fds.kind(fd, e) : "file";
2760
- if (kind === "sealed" || kind === "clipboard") return ROOT_IDS;
2761
- if (kind !== "file") return void 0;
2762
- try {
2763
- return this.o.fs.stat(pathOf(fd));
2764
- } catch (err) {
2765
- if (!GONE.has(err?.code)) throw err;
2766
- return void 0;
2767
- }
2768
- };
2769
- const pathOwned = (path, follow2) => {
2770
- if (this.synthetic(path)) return ROOT_IDS;
2771
- return follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
2772
- };
2773
- return wrap({
2774
- fd_chown: (fd, uid, gid) => {
2775
- const e = fds.get(fd);
2776
- const handle = e.type === "file" ? e.file.buffer.handle : void 0;
2777
- void chown(pathOf(fd), uid, gid, true, handle);
2778
- },
2779
- path_chown: (dirfd, p, l, uid, gid, flags) => void chown(at(dirfd, p, l), uid, gid, (flags & AT_SYMLINK_NOFOLLOW) === 0),
2780
- fd_owner: (fd, out) => {
2781
- if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2782
- owner(fdOwned(fd), out);
2783
- },
2784
- fd_filestat_owner: (fd, statOut, out) => {
2785
- if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2786
- this.writeFilestat(statOut, this.fdFilestat(fd));
2787
- owner(fdOwned(fd), out);
2788
- },
2789
- path_filestat_owner: (dirfd, lookup2, p, l, statOut, out) => {
2790
- const path = at(dirfd, p, l);
2791
- if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2792
- this.writeFilestat(statOut, this.pathFilestat(path, lookup2));
2793
- owner(pathOwned(path, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
2794
- },
2795
- path_owner: (dirfd, p, l, flags, out) => {
2796
- const path = at(dirfd, p, l);
2797
- if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
2798
- owner(pathOwned(path, (flags & AT_SYMLINK_NOFOLLOW) === 0), out);
2799
- },
2800
- path_access: (dirfd, p, l, amode, flags) => {
2801
- const path = at(dirfd, p, l);
2802
- const nofollow = (flags & AT_SYMLINK_NOFOLLOW) !== 0;
2803
- if (this.synthetic(path)) {
2804
- if (this.o.fs.owners && amode & 1) throw new WasiError("EACCES");
2805
- return;
2806
- }
2807
- const st = pathOwned(path, !nofollow);
2808
- if (amode & 2 && st.readonly) throw new WasiError("EROFS");
2809
- if (!this.o.fs.owners) return;
2810
- const kind = flags & AT_EACCESS ? "eaccess" : "access";
2811
- this.o.fs.access?.(path, amode & 7, kind, nofollow);
2812
- },
2813
- fd_chmod: (fd, mode) => void this.o.fs.chmod(pathOf(fd), mode & 4095),
2814
- path_chmod: (dirfd, p, l, mode, flags) => void this.o.fs.chmod(target(at(dirfd, p, l), flags), mode & 4095),
2815
- umask: (mask, out) => {
2816
- const old = this.o.kernel.call({ op: "proc-umask", mask });
2817
- mem.view().setUint32(out, old, true);
2818
- },
2819
- fd_mode: (fd, out) => {
2820
- const e = fds.get(fd);
2821
- const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
2822
- const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf2(this.o.fs.stat(pathOf(fd)));
2823
- mem.view().setUint32(out, mode, true);
2824
- },
2825
- path_mode: (dirfd, p, l, flags, out) => {
2826
- const path = at(dirfd, p, l);
2827
- if (this.synthetic(path) && deviceOf(path) === void 0)
2828
- return void mem.view().setUint32(out, SEALED_MODE, true);
2829
- const st = flags & AT_SYMLINK_NOFOLLOW ? this.o.fs.lstat(path) : this.o.fs.stat(path);
2830
- mem.view().setUint32(out, modeOf2(st), true);
2932
+ view.setUint32(out, count, true);
2933
+ }
2934
+ };
2935
+ }
2936
+ var INET4, INET6, UNIX, STREAM, DGRAM, RECV_DATA_TRUNCATED, RIFLAG_PEEK, MAX_DATAGRAM, ADDR_IP_SIZE, LOOPBACK, OPTIONS;
2937
+ var init_wasix_sockets = __esm({
2938
+ "src/process/wasi/wasix-sockets.ts"() {
2939
+ "use strict";
2940
+ init_datagram_wire();
2941
+ init_routes();
2942
+ init_wasi_abi();
2943
+ init_wasi_files();
2944
+ INET4 = 1;
2945
+ INET6 = 2;
2946
+ UNIX = 3;
2947
+ STREAM = 1;
2948
+ DGRAM = 2;
2949
+ RECV_DATA_TRUNCATED = 1;
2950
+ RIFLAG_PEEK = 1;
2951
+ MAX_DATAGRAM = 65536;
2952
+ ADDR_IP_SIZE = 18;
2953
+ LOOPBACK = "127.0.0.1";
2954
+ OPTIONS = {
2955
+ 1: [1, 15],
2956
+ 2: [1, 2],
2957
+ 3: [6, 1],
2958
+ 4: [1, 5],
2959
+ 6: [1, 6],
2960
+ 10: [1, 30],
2961
+ 11: [1, 4],
2962
+ 12: [1, 9],
2963
+ 14: [1, 10],
2964
+ 15: [1, 8],
2965
+ 16: [1, 7],
2966
+ 25: [1, 3]
2967
+ };
2968
+ }
2969
+ });
2970
+
2971
+ // src/process/wasi/wasi-host.ts
2972
+ function idOf(value2) {
2973
+ return value2 >>> 0 === 4294967295 ? void 0 : value2 >>> 0;
2974
+ }
2975
+ function linkedOf(st) {
2976
+ return (st.nlink ?? 1) > 1 ? st : void 0;
2977
+ }
2978
+ function linkedElsewhere(fs, path) {
2979
+ try {
2980
+ return linkedOf(fs.lstat(path));
2981
+ } catch {
2982
+ return void 0;
2983
+ }
2984
+ }
2985
+ function filetypeOf(s) {
2986
+ if (!s) return FILETYPE.UNKNOWN;
2987
+ if (s.isSymbolicLink) return FILETYPE.SYMBOLIC_LINK;
2988
+ if (s.isDirectory) return FILETYPE.DIRECTORY;
2989
+ return s.isFile ? FILETYPE.REGULAR_FILE : FILETYPE.UNKNOWN;
2990
+ }
2991
+ function filestatOf(path, s) {
2992
+ return {
2993
+ filetype: filetypeOf(s),
2994
+ size: BigInt(s.size),
2995
+ ino: s.ino !== void 0 ? BigInt(s.ino) : pathInode(path),
2996
+ ...s.nlink !== void 0 ? { nlink: BigInt(s.nlink) } : {},
2997
+ mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) * NS_PER_MS
2998
+ };
2999
+ }
3000
+ function kernelFiletype(kind) {
3001
+ switch (kind) {
3002
+ case "tty":
3003
+ case "sealed":
3004
+ case "clipboard":
3005
+ return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
3006
+ case "device":
3007
+ return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
3008
+ case "socket":
3009
+ return { filetype: FILETYPE.SOCKET_STREAM, seeks: false };
3010
+ case "dgram":
3011
+ return { filetype: FILETYPE.SOCKET_DGRAM, seeks: false };
3012
+ case "file":
3013
+ return { filetype: FILETYPE.REGULAR_FILE, seeks: true };
3014
+ default:
3015
+ return { filetype: FILETYPE.UNKNOWN, seeks: false };
3016
+ }
3017
+ }
3018
+ function direntRecord(next2, ino, name2, filetype) {
3019
+ const nameBytes = new TextEncoder().encode(name2);
3020
+ const record = new Uint8Array(SIZE.DIRENT + nameBytes.length);
3021
+ const v = new DataView(record.buffer);
3022
+ v.setBigUint64(0, BigInt(next2), true);
3023
+ v.setBigUint64(8, ino, true);
3024
+ v.setUint32(16, nameBytes.length, true);
3025
+ v.setUint8(20, filetype);
3026
+ record.set(nameBytes, SIZE.DIRENT);
3027
+ return record;
3028
+ }
3029
+ function wrap(table) {
3030
+ const out = {};
3031
+ for (const [name2, fn] of Object.entries(table)) {
3032
+ out[name2] = (...args) => {
3033
+ try {
3034
+ return fn(...args) ?? E.SUCCESS;
3035
+ } catch (e) {
3036
+ if (e instanceof WasiExit) throw e;
3037
+ if (e instanceof WasiError) return wasiErrnoOf(e.code);
3038
+ const code2 = e?.code;
3039
+ if (typeof code2 === "string") return wasiErrnoOf(code2);
3040
+ if (e instanceof RangeError) return E.FAULT;
3041
+ throw e;
3042
+ }
3043
+ };
3044
+ }
3045
+ return out;
3046
+ }
3047
+ var WasiExit, IDS, NS_PER_MS, AT_SYMLINK_NOFOLLOW, AT_EACCESS, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SIG_IGN, SEALED_MODE, WasiHost;
3048
+ var init_wasi_host = __esm({
3049
+ "src/process/wasi/wasi-host.ts"() {
3050
+ "use strict";
3051
+ init_dev_removal();
3052
+ init_physical_path();
3053
+ init_cpu_clock();
3054
+ init_cred();
3055
+ init_wasi_abi();
3056
+ init_wasi_fds();
3057
+ init_wasi_files();
3058
+ init_wasi_memory();
3059
+ init_wasi_poll();
3060
+ init_wasi_termios();
3061
+ init_wasix_sockets();
3062
+ WasiExit = class extends Error {
3063
+ code;
3064
+ constructor(code2) {
3065
+ super(`exit ${code2}`);
3066
+ this.code = code2;
3067
+ }
3068
+ };
3069
+ IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
3070
+ NS_PER_MS = 1000000n;
3071
+ AT_SYMLINK_NOFOLLOW = 1;
3072
+ AT_EACCESS = 2;
3073
+ ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
3074
+ GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
3075
+ S_IFIFO = 4096;
3076
+ DEFAULT_UMASK = 18;
3077
+ MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS;
3078
+ MAX_READ = 1024 * 1024;
3079
+ SIGPIPE_EXIT = 141;
3080
+ SIG_IGN = 1;
3081
+ SEALED_MODE = 8630;
3082
+ WasiHost = class {
3083
+ mem = new WasiMemory();
3084
+ fds;
3085
+ started = performance.now();
3086
+ cache;
3087
+ startCwd;
3088
+ interruptWakes = false;
3089
+ entered = false;
3090
+ onRaise;
3091
+ muted;
3092
+ signals;
3093
+ sigmask;
3094
+ linkedTls;
3095
+ linkedModules;
3096
+ interrupted;
3097
+ quietly = (fn) => fn();
3098
+ listening;
3099
+ o;
3100
+ constructor(o) {
3101
+ const { kernel } = o;
3102
+ const call2 = (req) => {
3103
+ if (req.op !== "fd-promote") this.fds.flushEarly();
3104
+ return kernel.call(req);
3105
+ };
3106
+ const sys = new Proxy(kernel.sys, {
3107
+ get: (target, name2) => {
3108
+ const member = Reflect.get(target, name2);
3109
+ if (typeof member !== "function") return member;
3110
+ return (...args) => {
3111
+ this.fds.flushEarly();
3112
+ return member.apply(target, args);
3113
+ };
2831
3114
  }
2832
3115
  });
3116
+ this.o = { ...o, kernel: { sys, call: call2 } };
3117
+ this.startCwd = o.cwd;
3118
+ this.fds = new WasiFds(this.o.kernel, o.fs);
3119
+ if (o.shared) this.fds.share(o.shared, true);
3120
+ else if (o.forked) this.fds.restore(o.forked.fds, o.forked.cloexec);
3121
+ else this.fds.setup(o.cwd, o.inherited ?? [], o.preopenRoot === true);
3122
+ this.listening = o.shared ? [] : this.fds.sockets();
2833
3123
  }
2834
- sliccImports() {
2835
- const { mem } = this;
2836
- const path = (p, l) => {
2837
- const text = mem.string(p, l);
2838
- return text === "" || text.startsWith("/") ? text : normalize(`${this.cwd}/${text}`);
3124
+ get cwd() {
3125
+ return this.fds.cwd() ?? this.startCwd;
3126
+ }
3127
+ created(path, mode) {
3128
+ const umask = this.o.kernel.call({ op: "proc-umask" });
3129
+ if (umask !== DEFAULT_UMASK) this.o.fs.chmod(path, mode & ~umask);
3130
+ }
3131
+ sliccTtyImports() {
3132
+ return wrap(sliccTty(this.mem, this.fds, this.o.kernel, () => this.interrupted?.()));
3133
+ }
3134
+ sliccFsImports() {
3135
+ const { mem, fds } = this;
3136
+ const at = (dirfd, p, l) => fds.resolve(dirfd, mem.string(p, l));
3137
+ const pathOf = (fd) => {
3138
+ const e = fds.get(fd);
3139
+ if (e.type === "dir") return e.path;
3140
+ if (e.type === "file") return e.file.path;
3141
+ const path = e.type === "kernel" && fds.kind(fd, e) === "file" ? this.kernelStat(fd).path : void 0;
3142
+ if (path === void 0) throw new WasiError("EBADF");
3143
+ return path;
2839
3144
  };
2840
- return wrap({
2841
- mount: (sp, sl, tp, tl, fp, fl, flags, dp, dl) => void this.o.kernel.call({
2842
- op: "mount",
2843
- source: mem.string(sp, sl),
2844
- target: path(tp, tl),
2845
- type: mem.string(fp, fl),
2846
- flags,
2847
- data: mem.string(dp, dl)
2848
- }),
2849
- umount2: (tp, tl, flags) => void this.o.kernel.call({ op: "umount", target: path(tp, tl), flags }),
2850
- cred_get: (out) => {
2851
- const cred = this.o.kernel.call({ op: "proc-cred" });
2852
- const view = mem.view();
2853
- view.getUint32(out + 20, true);
2854
- IDS.forEach((key, i) => void view.setUint32(out + i * 4, cred[key], true));
3145
+ const target = (path, flags) => {
3146
+ if (flags & AT_SYMLINK_NOFOLLOW && this.o.fs.lstat(path).isSymbolicLink) {
3147
+ throw new WasiError("ENOTSUP");
3148
+ }
3149
+ return path;
3150
+ };
3151
+ const modeOf2 = (st) => (st.mode ?? 0) & 4095;
3152
+ const chown = (path, uid, gid, follow2, handle) => {
3153
+ const { chown: own } = this.o.fs;
3154
+ if (!own) throw new WasiError("ENOSYS");
3155
+ own.call(this.o.fs, path, idOf(uid), idOf(gid), follow2, handle);
3156
+ };
3157
+ const caller = () => {
3158
+ const cred = this.o.kernel.call({ op: "proc-cred" });
3159
+ return [cred.euid, cred.egid];
3160
+ };
3161
+ const owner = (st, out) => {
3162
+ const [uid, gid] = st?.uid === void 0 ? caller() : [st.uid, st.gid];
3163
+ const view = mem.view();
3164
+ view.getUint32(out + 4, true);
3165
+ view.setUint32(out, uid, true);
3166
+ view.setUint32(out + 4, gid, true);
3167
+ };
3168
+ const fdOwned = (fd) => {
3169
+ const e = fds.get(fd);
3170
+ if (e.type === "device") return ROOT_IDS;
3171
+ const kind = e.type === "kernel" ? fds.kind(fd, e) : "file";
3172
+ if (kind === "sealed" || kind === "clipboard") return ROOT_IDS;
3173
+ if (kind !== "file") return void 0;
3174
+ try {
3175
+ return this.o.fs.stat(pathOf(fd));
3176
+ } catch (err) {
3177
+ if (!GONE.has(err?.code)) throw err;
3178
+ return void 0;
3179
+ }
3180
+ };
3181
+ const pathOwned = (path, follow2) => {
3182
+ if (this.synthetic(path)) return ROOT_IDS;
3183
+ return follow2 ? this.o.fs.stat(path) : this.o.fs.lstat(path);
3184
+ };
3185
+ return wrap({
3186
+ fd_chown: (fd, uid, gid) => {
3187
+ const e = fds.get(fd);
3188
+ const handle = e.type === "file" ? e.file.buffer.handle : void 0;
3189
+ void chown(pathOf(fd), uid, gid, true, handle);
3190
+ },
3191
+ path_chown: (dirfd, p, l, uid, gid, flags) => void chown(at(dirfd, p, l), uid, gid, (flags & AT_SYMLINK_NOFOLLOW) === 0),
3192
+ fd_owner: (fd, out) => {
3193
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
3194
+ owner(fdOwned(fd), out);
3195
+ },
3196
+ fd_filestat_owner: (fd, statOut, out) => {
3197
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
3198
+ this.writeFilestat(statOut, this.fdFilestat(fd));
3199
+ owner(fdOwned(fd), out);
3200
+ },
3201
+ path_filestat_owner: (dirfd, lookup2, p, l, statOut, out) => {
3202
+ const path = at(dirfd, p, l);
3203
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
3204
+ this.writeFilestat(statOut, this.pathFilestat(path, lookup2));
3205
+ owner(pathOwned(path, (lookup2 & LOOKUP_SYMLINK_FOLLOW) !== 0), out);
3206
+ },
3207
+ path_owner: (dirfd, p, l, flags, out) => {
3208
+ const path = at(dirfd, p, l);
3209
+ if (!this.o.fs.owners) throw new WasiError("ENOTSUP");
3210
+ owner(pathOwned(path, (flags & AT_SYMLINK_NOFOLLOW) === 0), out);
3211
+ },
3212
+ path_access: (dirfd, p, l, amode, flags) => {
3213
+ const path = at(dirfd, p, l);
3214
+ const nofollow = (flags & AT_SYMLINK_NOFOLLOW) !== 0;
3215
+ if (this.synthetic(path)) {
3216
+ if (this.o.fs.owners && amode & 1) throw new WasiError("EACCES");
3217
+ return;
3218
+ }
3219
+ const st = pathOwned(path, !nofollow);
3220
+ if (amode & 2 && st.readonly) throw new WasiError("EROFS");
3221
+ if (!this.o.fs.owners) return;
3222
+ const kind = flags & AT_EACCESS ? "eaccess" : "access";
3223
+ this.o.fs.access?.(path, amode & 7, kind, nofollow);
3224
+ },
3225
+ fd_chmod: (fd, mode) => void this.o.fs.chmod(pathOf(fd), mode & 4095),
3226
+ path_chmod: (dirfd, p, l, mode, flags) => void this.o.fs.chmod(target(at(dirfd, p, l), flags), mode & 4095),
3227
+ umask: (mask, out) => {
3228
+ const old = this.o.kernel.call({ op: "proc-umask", mask });
3229
+ mem.view().setUint32(out, old, true);
3230
+ },
3231
+ fd_mode: (fd, out) => {
3232
+ const e = fds.get(fd);
3233
+ const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
3234
+ const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf2(this.o.fs.stat(pathOf(fd)));
3235
+ mem.view().setUint32(out, mode, true);
3236
+ },
3237
+ path_mode: (dirfd, p, l, flags, out) => {
3238
+ const path = at(dirfd, p, l);
3239
+ if (this.synthetic(path) && deviceOf(path) === void 0)
3240
+ return void mem.view().setUint32(out, SEALED_MODE, true);
3241
+ const st = flags & AT_SYMLINK_NOFOLLOW ? this.o.fs.lstat(path) : this.o.fs.stat(path);
3242
+ mem.view().setUint32(out, modeOf2(st), true);
3243
+ }
3244
+ });
3245
+ }
3246
+ sliccImports() {
3247
+ const { mem } = this;
3248
+ const path = (p, l) => {
3249
+ const text = mem.string(p, l);
3250
+ return text === "" || text.startsWith("/") ? text : normalize(`${this.cwd}/${text}`);
3251
+ };
3252
+ return wrap({
3253
+ mount: (sp, sl, tp, tl, fp, fl, flags, dp, dl) => void this.o.kernel.call({
3254
+ op: "mount",
3255
+ source: mem.string(sp, sl),
3256
+ target: path(tp, tl),
3257
+ type: mem.string(fp, fl),
3258
+ flags,
3259
+ data: mem.string(dp, dl)
3260
+ }),
3261
+ umount2: (tp, tl, flags) => void this.o.kernel.call({ op: "umount", target: path(tp, tl), flags }),
3262
+ cred_get: (out) => {
3263
+ const cred = this.o.kernel.call({ op: "proc-cred" });
3264
+ const view = mem.view();
3265
+ view.getUint32(out + 20, true);
3266
+ IDS.forEach((key, i) => void view.setUint32(out + i * 4, cred[key], true));
2855
3267
  },
2856
3268
  cred_set: (...ids) => {
2857
3269
  const change = {};
@@ -3150,6 +3562,18 @@ var init_wasi_host = __esm({
3150
3562
  },
3151
3563
  sock_recv: (fd, iovs, n, riflags, outLen, outFlags) => {
3152
3564
  const e = this.socket(fd);
3565
+ if (this.fds.datagram(fd, e)) {
3566
+ return datagramCalls(this).recvFrom(
3567
+ fd,
3568
+ e.nonblock,
3569
+ iovs,
3570
+ n,
3571
+ riflags,
3572
+ outLen,
3573
+ outFlags,
3574
+ 0
3575
+ );
3576
+ }
3153
3577
  const peek = (riflags & RIFLAGS.PEEK) !== 0;
3154
3578
  const want = mem.capacity(iovs, n);
3155
3579
  const data = (riflags & RIFLAGS.WAITALL) !== 0 && !peek ? this.recvAll(fd, want, e.nonblock) : o.kernel.sys.read(fd, Math.min(want, MAX_READ), { nonblock: e.nonblock, peek });
@@ -3316,7 +3740,7 @@ var init_wasi_host = __esm({
3316
3740
  if (e.type === "kernel") {
3317
3741
  const kind = this.fds.kind(fd, e);
3318
3742
  if (kind === "device") this.interrupted?.();
3319
- ({ filetype, seeks } = kernelFiletype(kind));
3743
+ ({ filetype, seeks } = kernelFiletype(this.fds.datagram(fd, e) ? "dgram" : kind));
3320
3744
  if (e.nonblock) flags |= FDFLAGS.NONBLOCK;
3321
3745
  if (e.append) flags |= FDFLAGS.APPEND;
3322
3746
  } else if (e.type === "file") {
@@ -3869,7 +4293,7 @@ function importsContext({
3869
4293
  }
3870
4294
  function loopbackHost(host) {
3871
4295
  if (host === "localhost") return "127.0.0.1";
3872
- if (typeof host === "string" && LOOPBACK.test(host)) return host;
4296
+ if (typeof host === "string" && LOOPBACK2.test(host)) return host;
3873
4297
  throw new WasiError("EINVAL");
3874
4298
  }
3875
4299
  function network(raw, call2) {
@@ -3948,7 +4372,7 @@ function processes(host, call2, inThread) {
3948
4372
  }
3949
4373
  };
3950
4374
  }
3951
- var UID, LOOPBACK, SOL_SOCKET, SO_ERROR, STDIO;
4375
+ var UID, LOOPBACK2, SOL_SOCKET, SO_ERROR, STDIO;
3952
4376
  var init_wasi_imports = __esm({
3953
4377
  "src/process/wasi/wasi-imports.ts"() {
3954
4378
  "use strict";
@@ -3957,7 +4381,7 @@ var init_wasi_imports = __esm({
3957
4381
  init_wasi_threads();
3958
4382
  init_wasix_process();
3959
4383
  UID = 1e3;
3960
- LOOPBACK = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
4384
+ LOOPBACK2 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
3961
4385
  SOL_SOCKET = 1;
3962
4386
  SO_ERROR = 4;
3963
4387
  STDIO = ["stdin", "stdout", "stderr"];
@@ -4105,7 +4529,7 @@ var KERNEL_VERSION, OS_RELEASE;
4105
4529
  var init_version = __esm({
4106
4530
  "src/version.ts"() {
4107
4531
  "use strict";
4108
- KERNEL_VERSION = true ? "1.95.3" : "0.0.0-dev";
4532
+ KERNEL_VERSION = true ? "1.96.0" : "0.0.0-dev";
4109
4533
  OS_RELEASE = "6.0.0-slicc";
4110
4534
  }
4111
4535
  });
@@ -4597,7 +5021,7 @@ function flagsOf(o) {
4597
5021
  const access = write2 ? o.read ? O_RDWR3 : O_WRONLY3 : 0;
4598
5022
  return access | (o.append ? O_APPEND3 : 0);
4599
5023
  }
4600
- function openRequest(abs, o) {
5024
+ function openRequest2(abs, o) {
4601
5025
  return {
4602
5026
  op: "fd-open-vfs",
4603
5027
  path: abs,
@@ -4777,7 +5201,7 @@ function* aliasOf(fd, abs, o) {
4777
5201
  if (file) {
4778
5202
  const at = yield { op: "fd-vfs-stat", fd };
4779
5203
  if (!at.orphan)
4780
- return { fd: yield openRequest(at.path, { ...o, create: false }), file };
5204
+ return { fd: yield openRequest2(at.path, { ...o, create: false }), file };
4781
5205
  const wantWrite = o.write === true || o.append === true || o.truncate === true;
4782
5206
  if (wantWrite && info.access === "read") throw new JsCallError("EBADF", abs);
4783
5207
  if (!wantWrite && info.access === "write") throw new JsCallError("EBADF", abs);
@@ -4802,7 +5226,7 @@ function* opened(abs, o) {
4802
5226
  if (isExclusive(o)) throw new JsCallError("EEXIST", abs);
4803
5227
  switch (node.kind) {
4804
5228
  case "device":
4805
- return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
5229
+ return { fd: yield openRequest2(abs, { ...o, create: false }), file: false };
4806
5230
  case "tty":
4807
5231
  return { fd: yield { op: "fd-open-tty" }, file: false };
4808
5232
  case "clipboard":
@@ -5069,52 +5493,6 @@ var init_js_exit = __esm({
5069
5493
  }
5070
5494
  });
5071
5495
 
5072
- // src/kernel/net/loopback-names.ts
5073
- function isKernelLoopbackHost(hostname) {
5074
- const host = hostname.replace(/^\[(.*)\]$/, "$1").replace(/\.$/, "").toLowerCase();
5075
- return host === "localhost" || host.endsWith(".localhost") || host === "0.0.0.0" || LOOPBACK_V4.test(host) || LOOPBACK_V6.has(host) || MAPPED_V4.test(host);
5076
- }
5077
- function reserved(name2) {
5078
- const lower = name2.toLowerCase();
5079
- return lower === "localhost" || lower.endsWith(".localhost") || lower === HOST_LOOPBACK || lower === "wasmer.sh" || /^\d+(\.\d+){3}$/.test(lower);
5080
- }
5081
- function isHostname(name2) {
5082
- if (typeof name2 !== "string" || name2.length > 253 || reserved(name2)) return false;
5083
- return name2.split(".").every((l) => LABEL.test(l));
5084
- }
5085
- function hostnameOf(env) {
5086
- return isHostname(env.HOSTNAME) ? env.HOSTNAME : DEFAULT_HOSTNAME;
5087
- }
5088
- function ownNames(hostname) {
5089
- return [.../* @__PURE__ */ new Set([hostname.toLowerCase(), ...LIBC_HOSTNAMES])];
5090
- }
5091
- function hostsFile(hostname = DEFAULT_HOSTNAME) {
5092
- return [
5093
- "127.0.0.1 localhost localhost.localdomain",
5094
- "::1 localhost ip6-localhost",
5095
- `${HOSTNAME_ADDRESS} ${ownNames(hostname).join(" ")}`,
5096
- `${HOST_LOOPBACK_ADDRESS.join(".")} ${HOST_LOOPBACK}`,
5097
- ""
5098
- ].join("\n");
5099
- }
5100
- var HOST_LOOPBACK, HOST_LOOPBACK_ADDRESS, PAGE_LOOPBACK, PAGE_LOOPBACK_URL, LOOPBACK_V4, LOOPBACK_V6, MAPPED_V4, DEFAULT_HOSTNAME, HOSTNAME_ADDRESS, LIBC_HOSTNAMES, LABEL;
5101
- var init_loopback_names = __esm({
5102
- "src/kernel/net/loopback-names.ts"() {
5103
- "use strict";
5104
- HOST_LOOPBACK = "host.slicc.internal";
5105
- HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
5106
- PAGE_LOOPBACK = "kernel.localhost";
5107
- PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
5108
- LOOPBACK_V4 = /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
5109
- LOOPBACK_V6 = /* @__PURE__ */ new Set(["::1", "::", "0:0:0:0:0:0:0:1"]);
5110
- MAPPED_V4 = /^::ffff:7f[0-9a-f]{2}:[0-9a-f]{1,4}$/;
5111
- DEFAULT_HOSTNAME = "slicc";
5112
- HOSTNAME_ADDRESS = "127.0.1.1";
5113
- LIBC_HOSTNAMES = ["emscripten", "wasmer.sh"];
5114
- LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
5115
- }
5116
- });
5117
-
5118
5496
  // src/process/js/js-fetch.ts
5119
5497
  function withoutFragment(url) {
5120
5498
  url.hash = "";
@@ -8974,7 +9352,7 @@ function syncOps(kernel, shared) {
8974
9352
  existing = absent(err);
8975
9353
  }
8976
9354
  checkOpen(abs, options, existing);
8977
- const fd = kernel.json(openRequest(abs, options));
9355
+ const fd = kernel.json(openRequest2(abs, options));
8978
9356
  try {
8979
9357
  kernel.call({ op: "fd-vfs-stat", fd });
8980
9358
  } catch (err) {
@@ -9584,7 +9962,7 @@ async function vfsStat(kernel, abs, op, tryDev) {
9584
9962
  async function vfsOpen(kernel, abs, options, statOf, infos, handles) {
9585
9963
  const existing = await statOf(isExclusive(options) ? "lstat" : "stat", abs).catch(absent);
9586
9964
  checkOpen(abs, options, existing);
9587
- const fd = await kernel.json(openRequest(abs, options));
9965
+ const fd = await kernel.json(openRequest2(abs, options));
9588
9966
  try {
9589
9967
  await kernel.call({ op: "fd-vfs-stat", fd });
9590
9968
  } catch (err) {
@@ -13736,278 +14114,6 @@ var init_wasix_linker = __esm({
13736
14114
  }
13737
14115
  });
13738
14116
 
13739
- // src/kernel/net/routes.ts
13740
- function ipv4Bytes(text) {
13741
- const parts = text.split(".");
13742
- if (parts.length !== 4 || !parts.every((p) => /^\d{1,3}$/.test(p))) return void 0;
13743
- const bytes = parts.map(Number);
13744
- return bytes.every((b) => b <= 255) ? bytes : void 0;
13745
- }
13746
- function ipv6Groups(text) {
13747
- if (!text.includes(":")) return void 0;
13748
- let canonical;
13749
- try {
13750
- canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
13751
- } catch {
13752
- return void 0;
13753
- }
13754
- const [head, tail] = canonical.split("::");
13755
- const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
13756
- const front = part(head);
13757
- const back = part(tail);
13758
- return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
13759
- }
13760
- function toBits(values, width) {
13761
- return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
13762
- }
13763
- function addressBits(host) {
13764
- const v4 = ipv4Bytes(host);
13765
- if (v4) return { v6: false, bits: toBits(v4, 8) };
13766
- const v6 = ipv6Groups(host);
13767
- return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
13768
- }
13769
- function parsePrefix(text) {
13770
- const parts = text.trim().split("/");
13771
- if (parts.length > 2) return void 0;
13772
- const [address = "", size] = parts;
13773
- const parsed = addressBits(address);
13774
- if (!parsed) return void 0;
13775
- const max = parsed.v6 ? 128 : 32;
13776
- const length = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
13777
- if (length < 0 || length > max) return void 0;
13778
- return { ...parsed, length };
13779
- }
13780
- var HOST_ADDRESS, RESERVED;
13781
- var init_routes = __esm({
13782
- "src/kernel/net/routes.ts"() {
13783
- "use strict";
13784
- init_loopback_names();
13785
- HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
13786
- RESERVED = [
13787
- "0.0.0.0/8",
13788
- "127.0.0.0/8",
13789
- "169.254.0.0/16",
13790
- "224.0.0.0/4",
13791
- "240.0.0.0/4",
13792
- "::/96",
13793
- "::ffff:0:0/96",
13794
- "fe80::/10",
13795
- "ff00::/8"
13796
- ].map((p) => parsePrefix(p));
13797
- }
13798
- });
13799
-
13800
- // src/process/wasi/wasix-sockets.ts
13801
- function readAddr(view, ptr) {
13802
- const tag = view.getUint8(ptr);
13803
- if (tag === UNIX) {
13804
- let end = ptr + 2;
13805
- while (end < ptr + 110 && view.getUint8(end) !== 0) end++;
13806
- const path = new TextDecoder().decode(
13807
- new Uint8Array(view.buffer, ptr + 2, end - ptr - 2).slice()
13808
- );
13809
- return { family: "unix", path };
13810
- }
13811
- const port3 = view.getUint16(ptr + 2, true);
13812
- if (tag === INET4) {
13813
- const host = [0, 1, 2, 3].map((i) => view.getUint8(ptr + 4 + i)).join(".");
13814
- return { family: "inet", host, port: port3 };
13815
- }
13816
- if (tag === INET6) {
13817
- return { family: "inet", host: ipv6Host(new Uint8Array(view.buffer, ptr + 4, 16)), port: port3 };
13818
- }
13819
- throw new WasiError("EAFNOSUPPORT");
13820
- }
13821
- function ipv6Host(bytes) {
13822
- const zeros = (n) => bytes.subarray(0, n).every((b) => b === 0);
13823
- if (zeros(16)) return "0.0.0.0";
13824
- if (zeros(15) && bytes[15] === 1) return LOOPBACK2;
13825
- if (zeros(10) && bytes[10] === 255 && bytes[11] === 255) return bytes.subarray(12).join(".");
13826
- const groups = [0, 2, 4, 6, 8, 10, 12, 14].map(
13827
- (i) => (bytes[i] << 8 | bytes[i + 1]).toString(16)
13828
- );
13829
- return new URL(`http://[${groups.join(":")}]/`).hostname.slice(1, -1);
13830
- }
13831
- function writeAddr(view, ptr, addr) {
13832
- new Uint8Array(view.buffer, ptr, 110).fill(0);
13833
- if (!addr) return;
13834
- if (addr.family === "unix") {
13835
- view.setUint8(ptr, UNIX);
13836
- new Uint8Array(view.buffer, ptr + 2, 107).set(
13837
- new TextEncoder().encode(addr.path).subarray(0, 107)
13838
- );
13839
- return;
13840
- }
13841
- view.setUint16(ptr + 2, addr.port, true);
13842
- const groups = ipv4(addr.host) ? void 0 : ipv6Groups(addr.host);
13843
- if (groups) {
13844
- view.setUint8(ptr, INET6);
13845
- groups.forEach((g, i) => void view.setUint16(ptr + 4 + i * 2, g));
13846
- return;
13847
- }
13848
- view.setUint8(ptr, INET4);
13849
- const octets = ipv4(addr.host) ?? [127, 0, 0, 1];
13850
- octets.forEach((b, i) => void view.setUint8(ptr + 4 + i, b));
13851
- }
13852
- function ipBytes(host) {
13853
- const groups = ipv4(host) ? void 0 : ipv6Groups(host);
13854
- return groups ? groups.flatMap((g) => [g >> 8, g & 255]) : ipv4(host);
13855
- }
13856
- function ipv4(host) {
13857
- const parts = host.split(".");
13858
- if (parts.length !== 4) return void 0;
13859
- const bytes = parts.map((p) => /^\d{1,3}$/.test(p) ? Number(p) : Number.NaN);
13860
- return bytes.every((b) => b >= 0 && b <= 255) ? bytes : void 0;
13861
- }
13862
- function wasixSocketImports(host, preview1) {
13863
- const { mem, fds, o } = host;
13864
- const call2 = (req) => o.kernel.call(req);
13865
- const socket = (fd) => {
13866
- const e = fds.get(fd);
13867
- if (e.type !== "kernel" || fds.kind(fd, e) !== "socket") throw new WasiError("ENOTSOCK");
13868
- return e;
13869
- };
13870
- const option = (opt) => OPTIONS[opt];
13871
- return {
13872
- sock_open: (af, type, _proto, out) => {
13873
- if (af !== INET4 && af !== INET6 && af !== UNIX) throw new WasiError("EAFNOSUPPORT");
13874
- if (type !== STREAM) throw new WasiError("EPROTONOSUPPORT");
13875
- const fd = call2({ op: "sock-open", domain: af === UNIX ? "unix" : "inet" });
13876
- fds.adopt(fd, "socket", false);
13877
- mem.view().setUint32(out, fd, true);
13878
- },
13879
- sock_pair: (af, type, _proto, out1, out2) => {
13880
- if (af !== UNIX)
13881
- throw new WasiError(af === INET4 || af === INET6 ? "EOPNOTSUPP" : "EAFNOSUPPORT");
13882
- if (type !== STREAM) throw new WasiError("EPROTONOSUPPORT");
13883
- mem.view().setUint32(out1, 0, true);
13884
- mem.view().setUint32(out2, 0, true);
13885
- const [a, b] = call2({ op: "sock-pair", domain: "unix" });
13886
- fds.adopt(a, "socket", false);
13887
- fds.adopt(b, "socket", false);
13888
- mem.view().setUint32(out1, a, true);
13889
- mem.view().setUint32(out2, b, true);
13890
- },
13891
- sock_bind: (fd, addr) => {
13892
- socket(fd);
13893
- call2({ op: "sock-bind", fd, addr: readAddr(mem.view(), addr) });
13894
- },
13895
- sock_listen: (fd, backlog) => {
13896
- socket(fd);
13897
- call2({ op: "sock-listen", fd, backlog });
13898
- },
13899
- sock_connect: (fd, addr) => {
13900
- const e = socket(fd);
13901
- call2({ op: "sock-connect", fd, addr: readAddr(mem.view(), addr), nonblock: e.nonblock });
13902
- },
13903
- sock_accept_v2: (fd, flags, outFd, outAddr) => {
13904
- const e = socket(fd);
13905
- const r = call2({ op: "sock-accept", fd, nonblock: e.nonblock });
13906
- fds.adopt(r.fd, "socket", (flags & FDFLAGS.NONBLOCK) !== 0);
13907
- mem.view().setUint32(outFd, r.fd, true);
13908
- writeAddr(mem.view(), outAddr, r.peer);
13909
- },
13910
- sock_addr_local: (fd, out) => {
13911
- socket(fd);
13912
- writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: false }));
13913
- },
13914
- sock_addr_peer: (fd, out) => {
13915
- socket(fd);
13916
- writeAddr(mem.view(), out, call2({ op: "sock-name", fd, peer: true }));
13917
- },
13918
- sock_recv_from: (fd, iovs, n, riflags, outLen, outFlags, outAddr) => {
13919
- const r = preview1.sock_recv(
13920
- fd,
13921
- iovs,
13922
- n,
13923
- riflags,
13924
- outLen,
13925
- outFlags
13926
- );
13927
- if (r !== E.SUCCESS) return r;
13928
- writeAddr(mem.view(), outAddr, call2({ op: "sock-name", fd, peer: true }));
13929
- return E.SUCCESS;
13930
- },
13931
- sock_send_to: (fd, iovs, n, flags, _addr, out) => preview1.sock_send(fd, iovs, n, flags, out),
13932
- sock_status: (fd, out) => {
13933
- socket(fd);
13934
- mem.view().setUint8(out, 1);
13935
- },
13936
- sock_get_opt_flag: (fd, opt, out) => {
13937
- socket(fd);
13938
- const pair = option(opt);
13939
- const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
13940
- mem.view().setUint8(out, v ? 1 : 0);
13941
- },
13942
- sock_set_opt_flag: (fd, opt, flag) => {
13943
- socket(fd);
13944
- const pair = option(opt);
13945
- if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: flag ? 1 : 0 });
13946
- },
13947
- sock_get_opt_size: (fd, opt, out) => {
13948
- socket(fd);
13949
- const pair = option(opt);
13950
- const v = pair ? call2({ op: "sock-getopt", fd, level: pair[0], name: pair[1] }) : 0;
13951
- mem.view().setBigUint64(out, BigInt(v), true);
13952
- },
13953
- sock_set_opt_size: (fd, opt, size) => {
13954
- socket(fd);
13955
- const pair = option(opt);
13956
- if (pair) call2({ op: "sock-setopt", fd, level: pair[0], name: pair[1], value: Number(size) });
13957
- },
13958
- sock_get_opt_time: (fd, _opt, out) => {
13959
- socket(fd);
13960
- new Uint8Array(mem.view().buffer, out, 16).fill(0);
13961
- },
13962
- sock_set_opt_time: (fd) => void socket(fd),
13963
- sock_send_file: () => E.NOSYS,
13964
- resolve: (name2, len, _port, addrs, naddrs, out) => {
13965
- const found = call2({ op: "sock-resolve", name: mem.string(name2, len), family: 0 });
13966
- const ips = found.map(ipBytes).filter((ip) => ip !== void 0);
13967
- if (ips.length === 0) throw new WasiError("ENOENT");
13968
- if (naddrs < 1) throw new WasiError("EINVAL");
13969
- const view = mem.view();
13970
- const count = Math.min(ips.length, naddrs);
13971
- new Uint8Array(view.buffer, addrs, ADDR_IP_SIZE * count).fill(0);
13972
- for (let i = 0; i < count; i++) {
13973
- const at = addrs + i * ADDR_IP_SIZE;
13974
- view.setUint8(at, ips[i].length === 4 ? INET4 : INET6);
13975
- new Uint8Array(view.buffer, at + 2, ips[i].length).set(ips[i]);
13976
- }
13977
- view.setUint32(out, count, true);
13978
- }
13979
- };
13980
- }
13981
- var INET4, INET6, UNIX, STREAM, ADDR_IP_SIZE, LOOPBACK2, OPTIONS;
13982
- var init_wasix_sockets = __esm({
13983
- "src/process/wasi/wasix-sockets.ts"() {
13984
- "use strict";
13985
- init_routes();
13986
- init_wasi_abi();
13987
- init_wasi_files();
13988
- INET4 = 1;
13989
- INET6 = 2;
13990
- UNIX = 3;
13991
- STREAM = 1;
13992
- ADDR_IP_SIZE = 18;
13993
- LOOPBACK2 = "127.0.0.1";
13994
- OPTIONS = {
13995
- 1: [1, 15],
13996
- 2: [1, 2],
13997
- 3: [6, 1],
13998
- 4: [1, 5],
13999
- 6: [1, 6],
14000
- 10: [1, 30],
14001
- 11: [1, 4],
14002
- 12: [1, 9],
14003
- 14: [1, 10],
14004
- 15: [1, 8],
14005
- 16: [1, 7],
14006
- 25: [1, 3]
14007
- };
14008
- }
14009
- });
14010
-
14011
14117
  // src/process/wasi/wasix-host.ts
14012
14118
  function futexWait(view, index3, expected, ms, interrupted) {
14013
14119
  const deadline = performance.now() + ms;
@@ -14682,7 +14788,7 @@ function kernelOf(init, port3, hooks = { masks: () => null, raise: () => {
14682
14788
  const call2 = (req) => {
14683
14789
  const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
14684
14790
  if (!r.ok) throw new SyscallError(r.errno);
14685
- return r.kind === "json" ? r.json : void 0;
14791
+ return r.kind === "json" ? r.json : r.kind === "bytes" ? r.bytes : void 0;
14686
14792
  };
14687
14793
  const say = (text) => sys.write(2, new TextEncoder().encode(`${init.argv0}: ${text}
14688
14794
  `));