@ai-ecoverse/slicc-kernel 1.95.3 → 1.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/dist/index.js +71 -8
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +556 -178
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +710 -604
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +552 -212
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +783 -677
- package/dist/process-worker.js.map +4 -4
- package/dist/testing.js +45 -1
- package/dist/testing.js.map +2 -2
- package/package.json +1 -1
|
@@ -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/
|
|
2563
|
-
function
|
|
2564
|
-
|
|
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
|
-
|
|
2567
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
2577
|
-
|
|
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
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
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
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
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
|
|
2608
|
-
const
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
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
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
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
|
-
|
|
2720
|
-
|
|
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
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
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
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
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
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
}
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
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" &&
|
|
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,
|
|
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
|
-
|
|
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.
|
|
4532
|
+
KERNEL_VERSION = true ? "1.97.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
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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
|
`));
|