@ai-ecoverse/slicc-kernel 1.103.4 → 1.106.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -16
- package/dist/driver-worker.js +36 -1
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +89 -5
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +798 -295
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +2 -2
- package/dist/node-driver-worker.js +36 -1
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +489 -234
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +846 -315
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +426 -171
- package/dist/process-worker.js.map +4 -4
- package/dist/types/commands.d.ts +6 -1
- package/dist/types/fs/command-stat.d.ts +3 -0
- package/dist/types/fs/commands.d.ts +7 -1
- package/dist/types/fs/engines.d.ts +5 -0
- package/dist/types/fs/types.d.ts +1 -0
- package/dist/types/kernel/host.d.ts +1 -0
- package/dist/types/kernel/net/http-syscalls.d.ts +10 -0
- package/dist/types/kernel/net/http1.d.ts +1 -0
- package/dist/types/kernel/net/remote-transport.d.ts +18 -0
- package/dist/types/kernel/net/transport.d.ts +2 -0
- package/dist/types/kernel/process.d.ts +8 -0
- package/dist/types/launcher.d.ts +4 -0
- package/dist/types/process/js/js-kernel.d.ts +2 -1
- package/dist/types/process/process-signals.d.ts +3 -0
- package/dist/types/process/wasi/wasi-cred.d.ts +11 -0
- package/dist/types/process/wasi/wasi-files.d.ts +1 -0
- package/dist/types/process/wasi/wasi-host.d.ts +9 -0
- package/dist/types/process/wasi/wasi-sigmask.d.ts +7 -1
- package/dist/types/process/wasi/wasix-epoll.d.ts +3 -0
- package/dist/types/refused-command.d.ts +4 -0
- package/dist/types/transport.d.ts +1 -0
- package/package.json +12 -12
|
@@ -887,7 +887,7 @@ function pinnedIo(bridge, handle, rewriting) {
|
|
|
887
887
|
} : {}
|
|
888
888
|
};
|
|
889
889
|
}
|
|
890
|
-
var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, RING, RING_SIZE, SLOT, SHARED_IDS_BYTES, StatCache;
|
|
890
|
+
var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, CRED_GEN, RING, RING_SIZE, SLOT, SHARED_IDS_BYTES, StatCache;
|
|
891
891
|
var init_wasi_files = __esm({
|
|
892
892
|
"src/process/wasi/wasi-files.ts"() {
|
|
893
893
|
"use strict";
|
|
@@ -1109,6 +1109,7 @@ var init_wasi_files = __esm({
|
|
|
1109
1109
|
MAX_LINKS = 40;
|
|
1110
1110
|
MISS_TTL_MS = 20;
|
|
1111
1111
|
FS_GEN = 4;
|
|
1112
|
+
CRED_GEN = 5;
|
|
1112
1113
|
RING = 8;
|
|
1113
1114
|
RING_SIZE = 64;
|
|
1114
1115
|
SLOT = 3;
|
|
@@ -1598,6 +1599,69 @@ var init_cred = __esm({
|
|
|
1598
1599
|
}
|
|
1599
1600
|
});
|
|
1600
1601
|
|
|
1602
|
+
// src/kernel/signals.ts
|
|
1603
|
+
function defaultAction(sig) {
|
|
1604
|
+
if (sig === SIG.CONT) return "continue";
|
|
1605
|
+
if (STOPPING.has(sig)) return "stop";
|
|
1606
|
+
return IGNORED_BY_DEFAULT.has(sig) ? "ignore" : "terminate";
|
|
1607
|
+
}
|
|
1608
|
+
function sigbit(sig) {
|
|
1609
|
+
return 1 << sig;
|
|
1610
|
+
}
|
|
1611
|
+
function signalsIn(mask) {
|
|
1612
|
+
const out = [];
|
|
1613
|
+
for (let sig = 1; sig <= 31; sig++) if (mask & sigbit(sig)) out.push(sig);
|
|
1614
|
+
return out;
|
|
1615
|
+
}
|
|
1616
|
+
var SIG, IGNORED_BY_DEFAULT, STOPPING, SIGNAL_BY_NAME;
|
|
1617
|
+
var init_signals = __esm({
|
|
1618
|
+
"src/kernel/signals.ts"() {
|
|
1619
|
+
"use strict";
|
|
1620
|
+
SIG = {
|
|
1621
|
+
HUP: 1,
|
|
1622
|
+
INT: 2,
|
|
1623
|
+
QUIT: 3,
|
|
1624
|
+
ILL: 4,
|
|
1625
|
+
TRAP: 5,
|
|
1626
|
+
ABRT: 6,
|
|
1627
|
+
BUS: 7,
|
|
1628
|
+
FPE: 8,
|
|
1629
|
+
KILL: 9,
|
|
1630
|
+
USR1: 10,
|
|
1631
|
+
SEGV: 11,
|
|
1632
|
+
USR2: 12,
|
|
1633
|
+
PIPE: 13,
|
|
1634
|
+
ALRM: 14,
|
|
1635
|
+
TERM: 15,
|
|
1636
|
+
STKFLT: 16,
|
|
1637
|
+
CHLD: 17,
|
|
1638
|
+
CONT: 18,
|
|
1639
|
+
STOP: 19,
|
|
1640
|
+
TSTP: 20,
|
|
1641
|
+
TTIN: 21,
|
|
1642
|
+
TTOU: 22,
|
|
1643
|
+
URG: 23,
|
|
1644
|
+
XCPU: 24,
|
|
1645
|
+
XFSZ: 25,
|
|
1646
|
+
VTALRM: 26,
|
|
1647
|
+
PROF: 27,
|
|
1648
|
+
WINCH: 28,
|
|
1649
|
+
POLL: 29,
|
|
1650
|
+
PWR: 30,
|
|
1651
|
+
SYS: 31
|
|
1652
|
+
};
|
|
1653
|
+
IGNORED_BY_DEFAULT = /* @__PURE__ */ new Set([SIG.CHLD, SIG.URG, SIG.WINCH]);
|
|
1654
|
+
STOPPING = /* @__PURE__ */ new Set([SIG.STOP, SIG.TSTP, SIG.TTIN, SIG.TTOU]);
|
|
1655
|
+
SIGNAL_BY_NAME = {
|
|
1656
|
+
SIGINT: SIG.INT,
|
|
1657
|
+
SIGTERM: SIG.TERM,
|
|
1658
|
+
SIGKILL: SIG.KILL,
|
|
1659
|
+
SIGSTOP: SIG.STOP,
|
|
1660
|
+
SIGCONT: SIG.CONT
|
|
1661
|
+
};
|
|
1662
|
+
}
|
|
1663
|
+
});
|
|
1664
|
+
|
|
1601
1665
|
// src/process/wasi/slicc-lock.ts
|
|
1602
1666
|
function kindOf(type) {
|
|
1603
1667
|
if (type === F_RDLCK) return "read";
|
|
@@ -1712,6 +1776,48 @@ var init_slicc_sem = __esm({
|
|
|
1712
1776
|
}
|
|
1713
1777
|
});
|
|
1714
1778
|
|
|
1779
|
+
// src/process/wasi/wasi-cred.ts
|
|
1780
|
+
var CredCache;
|
|
1781
|
+
var init_wasi_cred = __esm({
|
|
1782
|
+
"src/process/wasi/wasi-cred.ts"() {
|
|
1783
|
+
"use strict";
|
|
1784
|
+
init_wasi_files();
|
|
1785
|
+
CredCache = class {
|
|
1786
|
+
cred;
|
|
1787
|
+
stamp = 0;
|
|
1788
|
+
fetch;
|
|
1789
|
+
shared;
|
|
1790
|
+
constructor(fetch, shared) {
|
|
1791
|
+
this.fetch = fetch;
|
|
1792
|
+
this.shared = shared;
|
|
1793
|
+
}
|
|
1794
|
+
gen() {
|
|
1795
|
+
return this.shared ? Atomics.load(this.shared, CRED_GEN) : 0;
|
|
1796
|
+
}
|
|
1797
|
+
get() {
|
|
1798
|
+
const gen = this.gen();
|
|
1799
|
+
if (this.cred === void 0 || this.stamp !== gen) {
|
|
1800
|
+
this.cred = this.fetch();
|
|
1801
|
+
this.stamp = gen;
|
|
1802
|
+
}
|
|
1803
|
+
return this.cred;
|
|
1804
|
+
}
|
|
1805
|
+
change(apply2) {
|
|
1806
|
+
const seen = this.gen();
|
|
1807
|
+
const cred = apply2();
|
|
1808
|
+
if (!this.shared) {
|
|
1809
|
+
this.cred = cred;
|
|
1810
|
+
return cred;
|
|
1811
|
+
}
|
|
1812
|
+
const was = Atomics.add(this.shared, CRED_GEN, 1);
|
|
1813
|
+
this.cred = was === seen ? cred : void 0;
|
|
1814
|
+
this.stamp = was + 1;
|
|
1815
|
+
return cred;
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1715
1821
|
// src/kernel/pipe.ts
|
|
1716
1822
|
var PIPE_CAPACITY;
|
|
1717
1823
|
var init_pipe = __esm({
|
|
@@ -2800,6 +2906,92 @@ var init_wasi_termios = __esm({
|
|
|
2800
2906
|
}
|
|
2801
2907
|
});
|
|
2802
2908
|
|
|
2909
|
+
// src/process/wasi/wasix-epoll.ts
|
|
2910
|
+
function timeoutMs(ns) {
|
|
2911
|
+
const value2 = BigInt.asUintN(64, ns);
|
|
2912
|
+
if (value2 === FOREVER) return -1;
|
|
2913
|
+
const ms = (value2 + NS_PER_MS2 - 1n) / NS_PER_MS2;
|
|
2914
|
+
return ms > BigInt(MAX_TIMEOUT_MS) ? -1 : Number(ms);
|
|
2915
|
+
}
|
|
2916
|
+
function wasixEpollImports(host) {
|
|
2917
|
+
const { mem, fds, o } = host;
|
|
2918
|
+
const call2 = (req) => o.kernel.call(req);
|
|
2919
|
+
const kernelFd = (fd, refusal2) => {
|
|
2920
|
+
const e = fds.find(fd);
|
|
2921
|
+
if (!e) throw new WasiError("EBADF");
|
|
2922
|
+
if (e.type !== "kernel") throw new WasiError(refusal2);
|
|
2923
|
+
};
|
|
2924
|
+
const writeEvents2 = (ptr, events) => {
|
|
2925
|
+
const view = mem.view();
|
|
2926
|
+
events.forEach((ev, i) => {
|
|
2927
|
+
const at = ptr + i * EVENT_SIZE;
|
|
2928
|
+
mem.bytes(at, EVENT_SIZE).fill(0);
|
|
2929
|
+
view.setUint32(at, ev.events, true);
|
|
2930
|
+
mem.bytes(at + DATA_OFFSET, DATA_SIZE).set(ev.data);
|
|
2931
|
+
});
|
|
2932
|
+
};
|
|
2933
|
+
return {
|
|
2934
|
+
epoll_create: (out) => {
|
|
2935
|
+
const fd = call2({ op: "epoll-create" });
|
|
2936
|
+
fds.adopt(fd, "stream", false);
|
|
2937
|
+
mem.view().setUint32(out, fd, true);
|
|
2938
|
+
},
|
|
2939
|
+
epoll_ctl: (epfd, op, fd, event) => {
|
|
2940
|
+
const how = (host.strictEpoll ? WASIX_OPS : DUAL_OPS)[op];
|
|
2941
|
+
if (!how) throw new WasiError("EINVAL");
|
|
2942
|
+
kernelFd(epfd, "EINVAL");
|
|
2943
|
+
kernelFd(fd, "EPERM");
|
|
2944
|
+
if (how !== "del" && event === 0) throw new WasiError("EINVAL");
|
|
2945
|
+
const events = event === 0 ? 0 : mem.view().getUint32(event, true);
|
|
2946
|
+
const data = event === 0 ? [] : [...mem.bytes(event + DATA_OFFSET, DATA_SIZE)];
|
|
2947
|
+
call2({ op: "epoll-ctl", epfd, how, fd, events, data });
|
|
2948
|
+
},
|
|
2949
|
+
epoll_wait: (epfd, ptr, maxevents, timeout, out) => {
|
|
2950
|
+
mem.view().setUint32(out, 0, true);
|
|
2951
|
+
if ((maxevents | 0) <= 0) throw new WasiError("EINVAL");
|
|
2952
|
+
kernelFd(epfd, "EINVAL");
|
|
2953
|
+
const max = Math.min(maxevents | 0, MAX_EVENTS);
|
|
2954
|
+
const ms = host.entered ? 0 : timeoutMs(timeout);
|
|
2955
|
+
const events = call2({ op: "epoll-wait", epfd, max, timeoutMs: ms });
|
|
2956
|
+
if (host.entered && events.length === 0 && timeoutMs(timeout) !== 0) return E.INTR;
|
|
2957
|
+
writeEvents2(ptr, events);
|
|
2958
|
+
mem.view().setUint32(out, events.length, true);
|
|
2959
|
+
return E.SUCCESS;
|
|
2960
|
+
},
|
|
2961
|
+
fd_event: (initial, flags, out) => {
|
|
2962
|
+
const value2 = BigInt.asUintN(64, initial);
|
|
2963
|
+
if (value2 > EVENTFD_MAX) throw new WasiError("EINVAL");
|
|
2964
|
+
const fd = call2({
|
|
2965
|
+
op: "eventfd-open",
|
|
2966
|
+
initial: value2.toString(),
|
|
2967
|
+
semaphore: (flags & EVENTFD_SEMAPHORE) !== 0
|
|
2968
|
+
});
|
|
2969
|
+
fds.adopt(fd, "stream", (flags & EVENTFD_NONBLOCK) !== 0);
|
|
2970
|
+
mem.view().setUint32(out, fd, true);
|
|
2971
|
+
}
|
|
2972
|
+
};
|
|
2973
|
+
}
|
|
2974
|
+
var EVENT_SIZE, DATA_OFFSET, DATA_SIZE, MAX_EVENTS, FOREVER, MAX_TIMEOUT_MS, NS_PER_MS2, EVENTFD_SEMAPHORE, EVENTFD_NONBLOCK, EVENTFD_MAX, WASIX_OPS, DUAL_OPS;
|
|
2975
|
+
var init_wasix_epoll = __esm({
|
|
2976
|
+
"src/process/wasi/wasix-epoll.ts"() {
|
|
2977
|
+
"use strict";
|
|
2978
|
+
init_wasi_abi();
|
|
2979
|
+
init_wasi_files();
|
|
2980
|
+
EVENT_SIZE = 32;
|
|
2981
|
+
DATA_OFFSET = 8;
|
|
2982
|
+
DATA_SIZE = 24;
|
|
2983
|
+
MAX_EVENTS = 4096;
|
|
2984
|
+
FOREVER = 0xffffffffffffffffn;
|
|
2985
|
+
MAX_TIMEOUT_MS = 2147483647;
|
|
2986
|
+
NS_PER_MS2 = 1000000n;
|
|
2987
|
+
EVENTFD_SEMAPHORE = 1;
|
|
2988
|
+
EVENTFD_NONBLOCK = 4;
|
|
2989
|
+
EVENTFD_MAX = 0xfffffffffffffffen;
|
|
2990
|
+
WASIX_OPS = ["add", "mod", "del"];
|
|
2991
|
+
DUAL_OPS = ["add", "set", "del", "mod"];
|
|
2992
|
+
}
|
|
2993
|
+
});
|
|
2994
|
+
|
|
2803
2995
|
// src/kernel/net/datagram-wire.ts
|
|
2804
2996
|
function decodeReceived(raw) {
|
|
2805
2997
|
const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
@@ -3232,7 +3424,7 @@ function filestatOf(path, s) {
|
|
|
3232
3424
|
size: BigInt(s.size),
|
|
3233
3425
|
ino: s.ino !== void 0 ? BigInt(s.ino) : pathInode(path),
|
|
3234
3426
|
...s.nlink !== void 0 ? { nlink: BigInt(s.nlink) } : {},
|
|
3235
|
-
mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) *
|
|
3427
|
+
mtimeNs: BigInt(Math.round(s.mtimeMs ?? 0)) * NS_PER_MS3
|
|
3236
3428
|
};
|
|
3237
3429
|
}
|
|
3238
3430
|
function kernelFiletype(kind) {
|
|
@@ -3282,7 +3474,7 @@ function wrap(table) {
|
|
|
3282
3474
|
}
|
|
3283
3475
|
return out;
|
|
3284
3476
|
}
|
|
3285
|
-
var WasiExit, IDS,
|
|
3477
|
+
var WasiExit, IDS, NS_PER_MS3, AT_SYMLINK_NOFOLLOW, AT_EACCESS, ROOT_IDS, GONE, S_IFIFO, DEFAULT_UMASK, MONOTONIC_BASE, MAX_READ, SIGPIPE_EXIT, SIG_IGN, SEALED_MODE, WasiHost;
|
|
3286
3478
|
var init_wasi_host = __esm({
|
|
3287
3479
|
"src/process/wasi/wasi-host.ts"() {
|
|
3288
3480
|
"use strict";
|
|
@@ -3290,14 +3482,17 @@ var init_wasi_host = __esm({
|
|
|
3290
3482
|
init_physical_path();
|
|
3291
3483
|
init_cpu_clock();
|
|
3292
3484
|
init_cred();
|
|
3485
|
+
init_signals();
|
|
3293
3486
|
init_slicc_lock();
|
|
3294
3487
|
init_slicc_sem();
|
|
3295
3488
|
init_wasi_abi();
|
|
3489
|
+
init_wasi_cred();
|
|
3296
3490
|
init_wasi_fds();
|
|
3297
3491
|
init_wasi_files();
|
|
3298
3492
|
init_wasi_memory();
|
|
3299
3493
|
init_wasi_poll();
|
|
3300
3494
|
init_wasi_termios();
|
|
3495
|
+
init_wasix_epoll();
|
|
3301
3496
|
init_wasix_sockets();
|
|
3302
3497
|
WasiExit = class extends Error {
|
|
3303
3498
|
code;
|
|
@@ -3307,26 +3502,30 @@ var init_wasi_host = __esm({
|
|
|
3307
3502
|
}
|
|
3308
3503
|
};
|
|
3309
3504
|
IDS = ["ruid", "euid", "suid", "rgid", "egid", "sgid"];
|
|
3310
|
-
|
|
3505
|
+
NS_PER_MS3 = 1000000n;
|
|
3311
3506
|
AT_SYMLINK_NOFOLLOW = 1;
|
|
3312
3507
|
AT_EACCESS = 2;
|
|
3313
3508
|
ROOT_IDS = Object.freeze({ uid: 0, gid: 0 });
|
|
3314
3509
|
GONE = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
|
|
3315
3510
|
S_IFIFO = 4096;
|
|
3316
3511
|
DEFAULT_UMASK = 18;
|
|
3317
|
-
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) *
|
|
3512
|
+
MONOTONIC_BASE = BigInt(Math.round(performance.timeOrigin)) * NS_PER_MS3;
|
|
3318
3513
|
MAX_READ = 1024 * 1024;
|
|
3319
|
-
SIGPIPE_EXIT =
|
|
3514
|
+
SIGPIPE_EXIT = 128 + SIG.PIPE;
|
|
3320
3515
|
SIG_IGN = 1;
|
|
3321
3516
|
SEALED_MODE = 8630;
|
|
3322
3517
|
WasiHost = class {
|
|
3323
3518
|
mem = new WasiMemory();
|
|
3324
3519
|
fds;
|
|
3520
|
+
creds;
|
|
3325
3521
|
started = performance.now();
|
|
3326
3522
|
cache;
|
|
3327
3523
|
startCwd;
|
|
3328
3524
|
interruptWakes = false;
|
|
3525
|
+
strictEpoll = false;
|
|
3329
3526
|
entered = false;
|
|
3527
|
+
enteredSignals = 0;
|
|
3528
|
+
raisedOnEntry;
|
|
3330
3529
|
onRaise;
|
|
3331
3530
|
muted;
|
|
3332
3531
|
signals;
|
|
@@ -3357,6 +3556,10 @@ var init_wasi_host = __esm({
|
|
|
3357
3556
|
this.o = { ...o, kernel: { sys, call: call2 } };
|
|
3358
3557
|
this.startCwd = o.cwd;
|
|
3359
3558
|
this.fds = new WasiFds(this.o.kernel, o.fs);
|
|
3559
|
+
this.creds = new CredCache(
|
|
3560
|
+
() => this.o.kernel.call({ op: "proc-cred" }),
|
|
3561
|
+
o.credGen ?? o.shared
|
|
3562
|
+
);
|
|
3360
3563
|
if (o.shared) this.fds.share(o.shared, true);
|
|
3361
3564
|
else if (o.forked) this.fds.restore(o.forked.fds, o.forked.cloexec);
|
|
3362
3565
|
else this.fds.setup(o.cwd, o.inherited ?? [], o.preopenRoot === true);
|
|
@@ -3396,7 +3599,7 @@ var init_wasi_host = __esm({
|
|
|
3396
3599
|
own.call(this.o.fs, path, idOf(uid), idOf(gid), follow2, handle);
|
|
3397
3600
|
};
|
|
3398
3601
|
const caller = () => {
|
|
3399
|
-
const cred = this.
|
|
3602
|
+
const cred = this.creds.get();
|
|
3400
3603
|
return [cred.euid, cred.egid];
|
|
3401
3604
|
};
|
|
3402
3605
|
const owner = (st, out) => {
|
|
@@ -3501,7 +3704,7 @@ var init_wasi_host = __esm({
|
|
|
3501
3704
|
}),
|
|
3502
3705
|
umount2: (tp, tl, flags) => void this.o.kernel.call({ op: "umount", target: path(tp, tl), flags }),
|
|
3503
3706
|
cred_get: (out) => {
|
|
3504
|
-
const cred = this.
|
|
3707
|
+
const cred = this.creds.get();
|
|
3505
3708
|
const view = mem.view();
|
|
3506
3709
|
view.getUint32(out + 20, true);
|
|
3507
3710
|
IDS.forEach((key, i) => void view.setUint32(out + i * 4, cred[key], true));
|
|
@@ -3511,7 +3714,7 @@ var init_wasi_host = __esm({
|
|
|
3511
3714
|
IDS.forEach((key, i) => {
|
|
3512
3715
|
if (ids[i] !== -1) change[key] = ids[i] >>> 0;
|
|
3513
3716
|
});
|
|
3514
|
-
void this.o.kernel.call({ op: "proc-setcred", change });
|
|
3717
|
+
void this.creds.change(() => this.o.kernel.call({ op: "proc-setcred", change }));
|
|
3515
3718
|
},
|
|
3516
3719
|
...semImports(this),
|
|
3517
3720
|
...lockImports({
|
|
@@ -3535,7 +3738,7 @@ var init_wasi_host = __esm({
|
|
|
3535
3738
|
}
|
|
3536
3739
|
}),
|
|
3537
3740
|
groups_get: (buf, cap, count) => {
|
|
3538
|
-
const { groups } = this.
|
|
3741
|
+
const { groups } = this.creds.get();
|
|
3539
3742
|
if (cap !== 0 && cap < groups.length) throw new WasiError("EINVAL");
|
|
3540
3743
|
const shown = cap === 0 ? [] : groups;
|
|
3541
3744
|
const view = mem.view();
|
|
@@ -3548,7 +3751,9 @@ var init_wasi_host = __esm({
|
|
|
3548
3751
|
if (n < 0 || n > MAX_GROUPS) throw new WasiError("EINVAL");
|
|
3549
3752
|
const view = mem.view();
|
|
3550
3753
|
const groups = Array.from({ length: n }, (_, i) => view.getUint32(buf + i * 4, true));
|
|
3551
|
-
void this.
|
|
3754
|
+
void this.creds.change(
|
|
3755
|
+
() => this.o.kernel.call({ op: "proc-setcred", change: { groups } })
|
|
3756
|
+
);
|
|
3552
3757
|
},
|
|
3553
3758
|
sigaction_set: (sig, disposition, flags) => {
|
|
3554
3759
|
if (!this.signals) return E.NOSYS;
|
|
@@ -3563,6 +3768,24 @@ var init_wasi_host = __esm({
|
|
|
3563
3768
|
view.setUint32(old + 4, oldHi, true);
|
|
3564
3769
|
}) : E.NOSYS,
|
|
3565
3770
|
sigmask_poll: (lo, hi, inPtr, outPtr, n, nevents) => this.sigmask ? this.maskedPoll(this.sigmask, [lo, hi], [inPtr, outPtr, n, nevents]) : E.NOSYS,
|
|
3771
|
+
sigmask_epoll_wait: (lo, hi, epfd, events, max, timeout, nevents) => this.sigmask ? this.maskedEpoll(
|
|
3772
|
+
this.sigmask,
|
|
3773
|
+
[lo, hi],
|
|
3774
|
+
nevents,
|
|
3775
|
+
(epoll) => epoll(epfd, events, max, timeout, nevents)
|
|
3776
|
+
) : E.NOSYS,
|
|
3777
|
+
sigwait: (lo, _hi, timeout, out) => {
|
|
3778
|
+
const mask = this.sigmask;
|
|
3779
|
+
if (!mask) return E.NOSYS;
|
|
3780
|
+
mem.view().setUint32(out, 0, true);
|
|
3781
|
+
return mask.sigwait(
|
|
3782
|
+
lo,
|
|
3783
|
+
timeout,
|
|
3784
|
+
(set) => void this.o.kernel.call({ op: "sig-waiting", tid: mask.tid, set }),
|
|
3785
|
+
(sig) => void mem.view().setUint32(out, sig, true),
|
|
3786
|
+
this.entered
|
|
3787
|
+
);
|
|
3788
|
+
},
|
|
3566
3789
|
sigpending_get: (out) => {
|
|
3567
3790
|
if (!this.sigmask) return E.NOSYS;
|
|
3568
3791
|
mem.view().setBigUint64(out, BigInt(this.sigmask.pending()), true);
|
|
@@ -3595,6 +3818,7 @@ var init_wasi_host = __esm({
|
|
|
3595
3818
|
try {
|
|
3596
3819
|
this.mem.view().setUint32(nevents, 0, true);
|
|
3597
3820
|
if (mask.deliverUnblocked()) return E.INTR;
|
|
3821
|
+
this.settleEntry(mask);
|
|
3598
3822
|
if (n > 0) return this.poll(inPtr, outPtr, n, nevents);
|
|
3599
3823
|
return this.entered ? E.INTR : this.suspend();
|
|
3600
3824
|
} finally {
|
|
@@ -3602,6 +3826,23 @@ var init_wasi_host = __esm({
|
|
|
3602
3826
|
mask.restore(old);
|
|
3603
3827
|
}
|
|
3604
3828
|
}
|
|
3829
|
+
epollWait;
|
|
3830
|
+
settleEntry(mask) {
|
|
3831
|
+
if (this.entered && (this.enteredSignals & ~mask.blockedBits()) === 0) this.entered = false;
|
|
3832
|
+
}
|
|
3833
|
+
maskedEpoll(mask, set, nevents, wait2) {
|
|
3834
|
+
const old = mask.swap(set[0], set[1]);
|
|
3835
|
+
try {
|
|
3836
|
+
this.mem.view().setUint32(nevents, 0, true);
|
|
3837
|
+
if (mask.deliverUnblocked()) return E.INTR;
|
|
3838
|
+
this.settleEntry(mask);
|
|
3839
|
+
this.epollWait ??= wasixEpollImports(this).epoll_wait;
|
|
3840
|
+
return wait2(this.epollWait) ?? E.SUCCESS;
|
|
3841
|
+
} finally {
|
|
3842
|
+
mask.deliverUnblocked();
|
|
3843
|
+
mask.restore(old);
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3605
3846
|
suspend() {
|
|
3606
3847
|
for (; ; ) {
|
|
3607
3848
|
try {
|
|
@@ -3624,7 +3865,7 @@ var init_wasi_host = __esm({
|
|
|
3624
3865
|
return this.cache;
|
|
3625
3866
|
}
|
|
3626
3867
|
now(id) {
|
|
3627
|
-
if (id === CLOCK.REALTIME) return BigInt(Date.now()) *
|
|
3868
|
+
if (id === CLOCK.REALTIME) return BigInt(Date.now()) * NS_PER_MS3;
|
|
3628
3869
|
if (id === CLOCK.MONOTONIC) {
|
|
3629
3870
|
return MONOTONIC_BASE + BigInt(Math.round(performance.now() * 1e6));
|
|
3630
3871
|
}
|
|
@@ -3958,7 +4199,7 @@ var init_wasi_host = __esm({
|
|
|
3958
4199
|
return this.fds.kind(fd, e) === "file" ? this.changed(fd, e, n) : n;
|
|
3959
4200
|
} catch (err) {
|
|
3960
4201
|
const broken = err.code === "EPIPE";
|
|
3961
|
-
if (broken && this.fds.kind(fd, e) !== "socket")
|
|
4202
|
+
if (broken && this.fds.kind(fd, e) !== "socket") this.brokenPipe();
|
|
3962
4203
|
throw err;
|
|
3963
4204
|
}
|
|
3964
4205
|
}
|
|
@@ -3970,6 +4211,18 @@ var init_wasi_host = __esm({
|
|
|
3970
4211
|
}
|
|
3971
4212
|
return this.file(fd, "write").write(data);
|
|
3972
4213
|
}
|
|
4214
|
+
brokenPipe() {
|
|
4215
|
+
let action;
|
|
4216
|
+
try {
|
|
4217
|
+
action = this.o.kernel.call({ op: "proc-kill-self", sig: SIG.PIPE, probe: true });
|
|
4218
|
+
} catch {
|
|
4219
|
+
action = "terminate";
|
|
4220
|
+
}
|
|
4221
|
+
if (action !== "terminate") return;
|
|
4222
|
+
const mask = this.sigmask;
|
|
4223
|
+
if (!mask?.blocks(SIG.PIPE)) throw new WasiExit(SIGPIPE_EXIT);
|
|
4224
|
+
this.o.kernel.call({ op: "thread-kill", tid: mask.tid, sig: SIG.PIPE });
|
|
4225
|
+
}
|
|
3973
4226
|
read(fd, max) {
|
|
3974
4227
|
const e = this.fds.get(fd);
|
|
3975
4228
|
if (e.type === "kernel") {
|
|
@@ -4153,7 +4406,7 @@ var init_wasi_host = __esm({
|
|
|
4153
4406
|
current ??= statOf(path);
|
|
4154
4407
|
return current[field2] ?? current.mtimeMs ?? now;
|
|
4155
4408
|
};
|
|
4156
|
-
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 /
|
|
4409
|
+
const pick = (set, setNow, value2, field2) => flags & setNow ? now : flags & set ? Number(value2 / NS_PER_MS3) : kept(field2);
|
|
4157
4410
|
(follow2 ? this.o.fs.utimes : this.o.fs.lutimes).call(
|
|
4158
4411
|
this.o.fs,
|
|
4159
4412
|
path,
|
|
@@ -4744,69 +4997,6 @@ var init_async_sab = __esm({
|
|
|
4744
4997
|
}
|
|
4745
4998
|
});
|
|
4746
4999
|
|
|
4747
|
-
// src/kernel/signals.ts
|
|
4748
|
-
function defaultAction(sig) {
|
|
4749
|
-
if (sig === SIG.CONT) return "continue";
|
|
4750
|
-
if (STOPPING.has(sig)) return "stop";
|
|
4751
|
-
return IGNORED_BY_DEFAULT.has(sig) ? "ignore" : "terminate";
|
|
4752
|
-
}
|
|
4753
|
-
function sigbit(sig) {
|
|
4754
|
-
return 1 << sig;
|
|
4755
|
-
}
|
|
4756
|
-
function signalsIn(mask) {
|
|
4757
|
-
const out = [];
|
|
4758
|
-
for (let sig = 1; sig <= 31; sig++) if (mask & sigbit(sig)) out.push(sig);
|
|
4759
|
-
return out;
|
|
4760
|
-
}
|
|
4761
|
-
var SIG, IGNORED_BY_DEFAULT, STOPPING, SIGNAL_BY_NAME;
|
|
4762
|
-
var init_signals = __esm({
|
|
4763
|
-
"src/kernel/signals.ts"() {
|
|
4764
|
-
"use strict";
|
|
4765
|
-
SIG = {
|
|
4766
|
-
HUP: 1,
|
|
4767
|
-
INT: 2,
|
|
4768
|
-
QUIT: 3,
|
|
4769
|
-
ILL: 4,
|
|
4770
|
-
TRAP: 5,
|
|
4771
|
-
ABRT: 6,
|
|
4772
|
-
BUS: 7,
|
|
4773
|
-
FPE: 8,
|
|
4774
|
-
KILL: 9,
|
|
4775
|
-
USR1: 10,
|
|
4776
|
-
SEGV: 11,
|
|
4777
|
-
USR2: 12,
|
|
4778
|
-
PIPE: 13,
|
|
4779
|
-
ALRM: 14,
|
|
4780
|
-
TERM: 15,
|
|
4781
|
-
STKFLT: 16,
|
|
4782
|
-
CHLD: 17,
|
|
4783
|
-
CONT: 18,
|
|
4784
|
-
STOP: 19,
|
|
4785
|
-
TSTP: 20,
|
|
4786
|
-
TTIN: 21,
|
|
4787
|
-
TTOU: 22,
|
|
4788
|
-
URG: 23,
|
|
4789
|
-
XCPU: 24,
|
|
4790
|
-
XFSZ: 25,
|
|
4791
|
-
VTALRM: 26,
|
|
4792
|
-
PROF: 27,
|
|
4793
|
-
WINCH: 28,
|
|
4794
|
-
POLL: 29,
|
|
4795
|
-
PWR: 30,
|
|
4796
|
-
SYS: 31
|
|
4797
|
-
};
|
|
4798
|
-
IGNORED_BY_DEFAULT = /* @__PURE__ */ new Set([SIG.CHLD, SIG.URG, SIG.WINCH]);
|
|
4799
|
-
STOPPING = /* @__PURE__ */ new Set([SIG.STOP, SIG.TSTP, SIG.TTIN, SIG.TTOU]);
|
|
4800
|
-
SIGNAL_BY_NAME = {
|
|
4801
|
-
SIGINT: SIG.INT,
|
|
4802
|
-
SIGTERM: SIG.TERM,
|
|
4803
|
-
SIGKILL: SIG.KILL,
|
|
4804
|
-
SIGSTOP: SIG.STOP,
|
|
4805
|
-
SIGCONT: SIG.CONT
|
|
4806
|
-
};
|
|
4807
|
-
}
|
|
4808
|
-
});
|
|
4809
|
-
|
|
4810
5000
|
// src/version.ts
|
|
4811
5001
|
function procVersion() {
|
|
4812
5002
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -4816,7 +5006,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
4816
5006
|
var init_version = __esm({
|
|
4817
5007
|
"src/version.ts"() {
|
|
4818
5008
|
"use strict";
|
|
4819
|
-
KERNEL_VERSION = true ? "1.
|
|
5009
|
+
KERNEL_VERSION = true ? "1.106.3" : "0.0.0-dev";
|
|
4820
5010
|
OS_RELEASE = "6.0.0-slicc";
|
|
4821
5011
|
}
|
|
4822
5012
|
});
|
|
@@ -4838,7 +5028,11 @@ function modeOf(mode) {
|
|
|
4838
5028
|
function callError(result, op) {
|
|
4839
5029
|
const { errno: errno2, message: message2 } = result;
|
|
4840
5030
|
const detailed = typeof message2 === "string" && message2 !== errno2 && DETAILED.has(op);
|
|
4841
|
-
return new JsCallError(
|
|
5031
|
+
return new JsCallError(
|
|
5032
|
+
errno2,
|
|
5033
|
+
detailed ? `${op}: ${message2}` : op,
|
|
5034
|
+
detailed ? message2 : void 0
|
|
5035
|
+
);
|
|
4842
5036
|
}
|
|
4843
5037
|
function untilAborted(work, signal) {
|
|
4844
5038
|
if (!signal) return work;
|
|
@@ -4865,10 +5059,12 @@ var init_js_kernel = __esm({
|
|
|
4865
5059
|
init_async_sab();
|
|
4866
5060
|
JsCallError = class extends Error {
|
|
4867
5061
|
code;
|
|
4868
|
-
|
|
5062
|
+
detail;
|
|
5063
|
+
constructor(code2, what, detail) {
|
|
4869
5064
|
super(`${what}: ${code2}`);
|
|
4870
5065
|
this.name = "JsCallError";
|
|
4871
5066
|
this.code = code2;
|
|
5067
|
+
this.detail = detail;
|
|
4872
5068
|
}
|
|
4873
5069
|
};
|
|
4874
5070
|
DETAILED = /* @__PURE__ */ new Set([
|
|
@@ -5783,6 +5979,29 @@ var init_js_exit = __esm({
|
|
|
5783
5979
|
});
|
|
5784
5980
|
|
|
5785
5981
|
// src/process/js/js-fetch.ts
|
|
5982
|
+
function cut(err) {
|
|
5983
|
+
if (!(err instanceof JsCallError) || err.code !== "EIO") return err;
|
|
5984
|
+
return Object.assign(new Error("other side closed"), {
|
|
5985
|
+
name: "SocketError",
|
|
5986
|
+
code: "UND_ERR_SOCKET"
|
|
5987
|
+
});
|
|
5988
|
+
}
|
|
5989
|
+
function givenNames(given) {
|
|
5990
|
+
if (given === void 0 || given instanceof Headers) return [];
|
|
5991
|
+
const pairs = Array.isArray(given) ? given : Object.entries(given);
|
|
5992
|
+
return pairs.map((pair) => String(pair[0]).toLowerCase());
|
|
5993
|
+
}
|
|
5994
|
+
function inOrder(headers, given) {
|
|
5995
|
+
const all = new Map(headers);
|
|
5996
|
+
const out = [];
|
|
5997
|
+
for (const name2 of [...givenNames(given), ...all.keys()]) {
|
|
5998
|
+
const value2 = all.get(name2);
|
|
5999
|
+
if (value2 === void 0) continue;
|
|
6000
|
+
all.delete(name2);
|
|
6001
|
+
out.push([name2, value2]);
|
|
6002
|
+
}
|
|
6003
|
+
return out;
|
|
6004
|
+
}
|
|
5786
6005
|
function withoutFragment(url) {
|
|
5787
6006
|
url.hash = "";
|
|
5788
6007
|
return url.href;
|
|
@@ -5809,9 +6028,7 @@ function checkUrl(url) {
|
|
|
5809
6028
|
if (protocol !== "http:" && protocol !== "https:") {
|
|
5810
6029
|
throw failed(new JsCallError("EPROTONOSUPPORT", protocol));
|
|
5811
6030
|
}
|
|
5812
|
-
if (badPort(parsed)
|
|
5813
|
-
throw failed(Object.assign(new Error("bad port"), { code: "EACCES" }));
|
|
5814
|
-
}
|
|
6031
|
+
if (badPort(parsed)) throw failed(new Error("bad port"));
|
|
5815
6032
|
}
|
|
5816
6033
|
function rewrite(hop, status2, location) {
|
|
5817
6034
|
const next2 = new URL(location, hop.url);
|
|
@@ -5823,6 +6040,9 @@ function rewrite(hop, status2, location) {
|
|
|
5823
6040
|
);
|
|
5824
6041
|
}
|
|
5825
6042
|
const toGet = (status2 === 301 || status2 === 302) && hop.method === "POST" || status2 === 303 && hop.method !== "GET" && hop.method !== "HEAD";
|
|
6043
|
+
if (hop.stream && !toGet) {
|
|
6044
|
+
throw failed(new JsCallError("EIO", `a ${status2} redirect would send a streamed body again`));
|
|
6045
|
+
}
|
|
5826
6046
|
const crossOrigin = next2.origin !== new URL(hop.url).origin;
|
|
5827
6047
|
const headers = hop.headers.filter(
|
|
5828
6048
|
([name2]) => !(toGet && BODY_HEADERS.has(name2.toLowerCase())) && !(crossOrigin && CREDENTIALS.has(name2.toLowerCase()))
|
|
@@ -5989,6 +6209,44 @@ async function bodyOf(request, cap, signal) {
|
|
|
5989
6209
|
}
|
|
5990
6210
|
return out;
|
|
5991
6211
|
}
|
|
6212
|
+
function streams(known, request, init, url) {
|
|
6213
|
+
if (known.streamingBodies !== true || !(init?.body instanceof ReadableStream)) return false;
|
|
6214
|
+
return request.method !== "GET" && request.method !== "HEAD" && !local2(url);
|
|
6215
|
+
}
|
|
6216
|
+
async function pump(kernel, handle, stream, signal) {
|
|
6217
|
+
const reader = stream.getReader();
|
|
6218
|
+
const stop = () => void reader.cancel(signal.reason).catch(() => void 0);
|
|
6219
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
6220
|
+
try {
|
|
6221
|
+
await pumpFrom(kernel, handle, reader, signal);
|
|
6222
|
+
} finally {
|
|
6223
|
+
signal.removeEventListener("abort", stop);
|
|
6224
|
+
}
|
|
6225
|
+
}
|
|
6226
|
+
async function pumpFrom(kernel, handle, reader, signal) {
|
|
6227
|
+
for (; ; ) {
|
|
6228
|
+
let bytes;
|
|
6229
|
+
try {
|
|
6230
|
+
const next2 = await reader.read();
|
|
6231
|
+
if (next2.done) break;
|
|
6232
|
+
bytes = bytesOf(next2.value);
|
|
6233
|
+
} catch (err) {
|
|
6234
|
+
await reader.cancel(err).catch(() => void 0);
|
|
6235
|
+
await kernel.raw({ op: "net-close", handle });
|
|
6236
|
+
return;
|
|
6237
|
+
}
|
|
6238
|
+
if (bytes.length === 0) continue;
|
|
6239
|
+
const taken = await kernel.blocking({ op: "net-write", handle, bytes }, signal).then(
|
|
6240
|
+
() => true,
|
|
6241
|
+
() => false
|
|
6242
|
+
);
|
|
6243
|
+
if (!taken) {
|
|
6244
|
+
await reader.cancel().catch(() => void 0);
|
|
6245
|
+
return;
|
|
6246
|
+
}
|
|
6247
|
+
}
|
|
6248
|
+
await kernel.raw({ op: "net-end", handle });
|
|
6249
|
+
}
|
|
5992
6250
|
function fetchOp(kernel) {
|
|
5993
6251
|
const traits = /* @__PURE__ */ new Map();
|
|
5994
6252
|
const traitsOf = (url) => {
|
|
@@ -6008,8 +6266,9 @@ function fetchOp(kernel) {
|
|
|
6008
6266
|
url: hop.url,
|
|
6009
6267
|
method: hop.method,
|
|
6010
6268
|
headers: hop.headers,
|
|
6011
|
-
...hop.body ? { body: hop.body } : {}
|
|
6269
|
+
...hop.stream ? { stream: true } : hop.body ? { body: hop.body } : {}
|
|
6012
6270
|
});
|
|
6271
|
+
if (hop.stream) void pump(kernel, handle, hop.stream, signal);
|
|
6013
6272
|
try {
|
|
6014
6273
|
const r = await kernel.blocking({ op: "net-head", handle }, signal);
|
|
6015
6274
|
signal.throwIfAborted();
|
|
@@ -6041,7 +6300,7 @@ function fetchOp(kernel) {
|
|
|
6041
6300
|
} catch (err) {
|
|
6042
6301
|
settle();
|
|
6043
6302
|
await close(handle);
|
|
6044
|
-
throw signal.aborted ? signal.reason : new TypeError("terminated", { cause: err });
|
|
6303
|
+
throw signal.aborted ? signal.reason : new TypeError("terminated", { cause: cut(err) });
|
|
6045
6304
|
}
|
|
6046
6305
|
const bytes = r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
|
|
6047
6306
|
if (bytes.length > 0) {
|
|
@@ -6103,15 +6362,17 @@ function fetchOp(kernel) {
|
|
|
6103
6362
|
throw failed(new JsCallError("ENOTSUP", `redirect: ${request.redirect}`));
|
|
6104
6363
|
}
|
|
6105
6364
|
const url = withoutFragment(new URL(request.url));
|
|
6106
|
-
const
|
|
6365
|
+
const streamed = streams(known, request, init, url);
|
|
6366
|
+
const bytes = streamed ? void 0 : await bodyOf(request, known.maxRequestBody, signal);
|
|
6107
6367
|
if (bytes === OVER) {
|
|
6108
6368
|
return withMeta(plain(413, `request body over ${known.maxRequestBody} bytes`), url, false);
|
|
6109
6369
|
}
|
|
6110
6370
|
let hop = {
|
|
6111
6371
|
url,
|
|
6112
6372
|
method: request.method,
|
|
6113
|
-
headers:
|
|
6114
|
-
body: bytes
|
|
6373
|
+
headers: inOrder(request.headers, init?.headers),
|
|
6374
|
+
body: bytes,
|
|
6375
|
+
...streamed && request.body ? { stream: request.body } : {}
|
|
6115
6376
|
};
|
|
6116
6377
|
for (let hops = 0; ; hops++) {
|
|
6117
6378
|
const head = await send(hop, signal);
|
|
@@ -6122,8 +6383,7 @@ function fetchOp(kernel) {
|
|
|
6122
6383
|
return respond(head, hop.method, redirected, known.encodedBodies, signal);
|
|
6123
6384
|
}
|
|
6124
6385
|
await close(head.handle);
|
|
6125
|
-
if (request.redirect === "error")
|
|
6126
|
-
throw failed(new JsCallError("EREDIRECT", "unexpected redirect"));
|
|
6386
|
+
if (request.redirect === "error") throw failed(new Error("unexpected redirect"));
|
|
6127
6387
|
if (hops >= MAX_REDIRECTS) throw failed(new JsCallError("ELOOP", hop.url));
|
|
6128
6388
|
[hop, known] = await redirect(hop, head.status, location, known);
|
|
6129
6389
|
}
|
|
@@ -10228,6 +10488,12 @@ var init_js_tty = __esm({
|
|
|
10228
10488
|
function failed4(err) {
|
|
10229
10489
|
return new TypeError("websocket failed", { cause: err });
|
|
10230
10490
|
}
|
|
10491
|
+
function openError(err) {
|
|
10492
|
+
if (!(err instanceof JsCallError) || err.detail === void 0) return err;
|
|
10493
|
+
const prefix = `${err.code}: `;
|
|
10494
|
+
const message2 = err.detail.startsWith(prefix) ? err.detail.slice(prefix.length) : err.detail;
|
|
10495
|
+
return Object.assign(new Error(message2), { code: err.code });
|
|
10496
|
+
}
|
|
10231
10497
|
function socketUrl(input) {
|
|
10232
10498
|
const url = new URL(input);
|
|
10233
10499
|
if (url.protocol === "http:") url.protocol = "ws:";
|
|
@@ -10269,7 +10535,7 @@ function websocketOp(kernel) {
|
|
|
10269
10535
|
protocol = (r.ok && r.kind === "json" ? r.json : {}).protocol;
|
|
10270
10536
|
} catch (err) {
|
|
10271
10537
|
await free();
|
|
10272
|
-
throw signal.aborted ? signal.reason : failed4(err);
|
|
10538
|
+
throw signal.aborted ? signal.reason : failed4(openError(err));
|
|
10273
10539
|
}
|
|
10274
10540
|
let settle;
|
|
10275
10541
|
let lose;
|
|
@@ -11807,7 +12073,7 @@ function orphanContents(stream) {
|
|
|
11807
12073
|
if (live.ranged) return live.ranged.read(0, live.ranged.size());
|
|
11808
12074
|
return live.data?.slice(0, live.len ?? live.data.length) ?? new Uint8Array(0);
|
|
11809
12075
|
}
|
|
11810
|
-
function vfsPromoter(Fs, sys,
|
|
12076
|
+
function vfsPromoter(Fs, sys, streams2, livePath) {
|
|
11811
12077
|
const promoted = /* @__PURE__ */ new Map();
|
|
11812
12078
|
return (stream) => {
|
|
11813
12079
|
if (stream.sliccKernelFd !== void 0 || !isVfsFile(Fs, stream)) return;
|
|
@@ -11827,11 +12093,11 @@ function vfsPromoter(Fs, sys, streams, livePath) {
|
|
|
11827
12093
|
);
|
|
11828
12094
|
promoted.set(stream.shared, kfd);
|
|
11829
12095
|
}
|
|
11830
|
-
|
|
12096
|
+
streams2.attachFile(stream, kfd);
|
|
11831
12097
|
};
|
|
11832
12098
|
}
|
|
11833
|
-
function describeForFork(Fs, sys,
|
|
11834
|
-
const promote = vfsPromoter(Fs, sys,
|
|
12099
|
+
function describeForFork(Fs, sys, streams2, livePath) {
|
|
12100
|
+
const promote = vfsPromoter(Fs, sys, streams2, livePath);
|
|
11835
12101
|
const out = [];
|
|
11836
12102
|
for (const stream of Fs.streams) {
|
|
11837
12103
|
if (!stream) continue;
|
|
@@ -11855,7 +12121,7 @@ function kernelEntry2(stream, kernel) {
|
|
|
11855
12121
|
const access = kind === "tty" ? O_RDWR4 : (stream.flags ?? O_RDWR4) & O_ACCMODE4;
|
|
11856
12122
|
return { fd: stream.fd, kernel, kind, flags: access, ...cloexec };
|
|
11857
12123
|
}
|
|
11858
|
-
function describeInherited(Fs, sys,
|
|
12124
|
+
function describeInherited(Fs, sys, streams2, livePath, actions = []) {
|
|
11859
12125
|
const table = /* @__PURE__ */ new Map();
|
|
11860
12126
|
for (const stream of Fs.streams) {
|
|
11861
12127
|
if (stream) table.set(stream.fd, { stream, cloexec: closesOnExec(stream) });
|
|
@@ -11870,7 +12136,7 @@ function describeInherited(Fs, sys, streams, livePath, actions = []) {
|
|
|
11870
12136
|
for (const [fd, { stream, cloexec }] of table) {
|
|
11871
12137
|
if (fd > 2 && !cloexec) slots3.set(fd, stream);
|
|
11872
12138
|
}
|
|
11873
|
-
const promote = vfsPromoter(Fs, sys,
|
|
12139
|
+
const promote = vfsPromoter(Fs, sys, streams2, livePath);
|
|
11874
12140
|
const out = [];
|
|
11875
12141
|
for (const [fd, stream] of slots3) {
|
|
11876
12142
|
promote(stream);
|
|
@@ -11899,50 +12165,50 @@ function place(Fs, stream, fd) {
|
|
|
11899
12165
|
Fs.closeStream(stream.fd);
|
|
11900
12166
|
return moved;
|
|
11901
12167
|
}
|
|
11902
|
-
function placeholder(Fs,
|
|
12168
|
+
function placeholder(Fs, streams2, entry) {
|
|
11903
12169
|
const access = entry.flags ?? O_RDWR4;
|
|
11904
|
-
if (entry.kind === "socket") return
|
|
12170
|
+
if (entry.kind === "socket") return streams2.socketStream(access);
|
|
11905
12171
|
if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR4);
|
|
11906
12172
|
if (entry.kind === "stream" || entry.kind === "clipboard" || entry.kind === "sealed")
|
|
11907
12173
|
return Fs.open("/dev/null", access);
|
|
11908
12174
|
Fs.mkdirTree(PLACEHOLDER_DIR);
|
|
11909
12175
|
return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`, access | O_CREAT3);
|
|
11910
12176
|
}
|
|
11911
|
-
function asFifo(stream,
|
|
11912
|
-
const inos = streamInos.get(
|
|
11913
|
-
streamInos.set(
|
|
12177
|
+
function asFifo(stream, streams2, identity) {
|
|
12178
|
+
const inos = streamInos.get(streams2) ?? /* @__PURE__ */ new Map();
|
|
12179
|
+
streamInos.set(streams2, inos);
|
|
11914
12180
|
const fixed = inos.get(identity) ?? nextStreamIno++;
|
|
11915
12181
|
inos.set(identity, fixed);
|
|
11916
12182
|
const node = stream.node;
|
|
11917
|
-
|
|
12183
|
+
streams2.describe(stream, `pipe:[${fixed}]`, () => ({
|
|
11918
12184
|
...node.node_ops?.getattr?.(node),
|
|
11919
12185
|
mode: FIFO_MODE,
|
|
11920
12186
|
ino: fixed,
|
|
11921
12187
|
size: 0
|
|
11922
12188
|
}));
|
|
11923
12189
|
}
|
|
11924
|
-
function placeKernelStream(Fs,
|
|
11925
|
-
const stream = place(Fs, placeholder(Fs,
|
|
12190
|
+
function placeKernelStream(Fs, streams2, entry) {
|
|
12191
|
+
const stream = place(Fs, placeholder(Fs, streams2, entry), entry.fd);
|
|
11926
12192
|
if (entry.kind === "file") {
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
} else if (entry.kind === "socket")
|
|
11930
|
-
else
|
|
11931
|
-
if (entry.kind === "clipboard")
|
|
11932
|
-
if (entry.kind === "sealed" || entry.kind === "clipboard")
|
|
11933
|
-
if (entry.kind === "tty")
|
|
12193
|
+
streams2.attachFile(stream, entry.kernel);
|
|
12194
|
+
streams2.sizeFromKernel(stream, entry.kernel);
|
|
12195
|
+
} else if (entry.kind === "socket") streams2.attachSocket(stream, entry.kernel);
|
|
12196
|
+
else streams2.attach(stream, entry.kernel, entry.kind === "tty");
|
|
12197
|
+
if (entry.kind === "clipboard") streams2.reportClose(entry.kernel);
|
|
12198
|
+
if (entry.kind === "sealed" || entry.kind === "clipboard") streams2.nameDevice(stream, entry.kind);
|
|
12199
|
+
if (entry.kind === "tty") streams2.nameTerminal(stream);
|
|
11934
12200
|
if (entry.kind === "stream") {
|
|
11935
|
-
asFifo(stream,
|
|
12201
|
+
asFifo(stream, streams2, entry.desc !== void 0 ? `d${entry.desc}` : `k${entry.kernel}`);
|
|
11936
12202
|
}
|
|
11937
12203
|
setCloseOnExec(stream, entry.cloexec === true);
|
|
11938
12204
|
return stream;
|
|
11939
12205
|
}
|
|
11940
|
-
function restoreForkedStreams(Fs,
|
|
12206
|
+
function restoreForkedStreams(Fs, streams2, table) {
|
|
11941
12207
|
for (const stream of Fs.streams) if (stream) Fs.closeStream(stream.fd);
|
|
11942
12208
|
for (const entry of table) {
|
|
11943
12209
|
try {
|
|
11944
12210
|
if ("kernel" in entry) {
|
|
11945
|
-
placeKernelStream(Fs,
|
|
12211
|
+
placeKernelStream(Fs, streams2, entry);
|
|
11946
12212
|
} else {
|
|
11947
12213
|
const placed = place(
|
|
11948
12214
|
Fs,
|
|
@@ -12010,14 +12276,14 @@ function forkRestarted(deps, state, snapshotAt) {
|
|
|
12010
12276
|
let memory = state.memory;
|
|
12011
12277
|
let seen = snapshotAt;
|
|
12012
12278
|
return restarted2(() => {
|
|
12013
|
-
const
|
|
12279
|
+
const streams2 = deps.describeFork();
|
|
12014
12280
|
const now = deps.deliveries?.();
|
|
12015
12281
|
if (now !== seen) {
|
|
12016
12282
|
seen = now;
|
|
12017
12283
|
const live = deps.memory?.();
|
|
12018
12284
|
if (live) memory = new Uint8Array(live.buffer).slice();
|
|
12019
12285
|
}
|
|
12020
|
-
const forked = { ...state, memory, streams, cwd: deps.Fs.cwd() };
|
|
12286
|
+
const forked = { ...state, memory, streams: streams2, cwd: deps.Fs.cwd() };
|
|
12021
12287
|
return deps.transport.call(
|
|
12022
12288
|
{ op: "proc-fork", state: forked, restart: true },
|
|
12023
12289
|
Infinity,
|
|
@@ -12329,6 +12595,8 @@ var init_process_signals = __esm({
|
|
|
12329
12595
|
unwinding = false;
|
|
12330
12596
|
quieted = 0;
|
|
12331
12597
|
delivered = 0;
|
|
12598
|
+
raised = 0;
|
|
12599
|
+
entering = 0;
|
|
12332
12600
|
raw;
|
|
12333
12601
|
header;
|
|
12334
12602
|
hooks;
|
|
@@ -12391,9 +12659,18 @@ var init_process_signals = __esm({
|
|
|
12391
12659
|
const header = this.header;
|
|
12392
12660
|
const pending = Atomics.load(header, SAB_I_SIGNALS) & ~Atomics.load(header, SAB_I_BLOCKED) | Atomics.load(header, SAB_I_TIMERS) | Atomics.load(header, SAB_I_KILLED);
|
|
12393
12661
|
if (pending === 0) return false;
|
|
12394
|
-
this.
|
|
12662
|
+
if (this.entering === 0) this.raised = this.quieted > 0 ? -1 : 0;
|
|
12663
|
+
this.entering++;
|
|
12664
|
+
try {
|
|
12665
|
+
this.deliver();
|
|
12666
|
+
} finally {
|
|
12667
|
+
this.entering--;
|
|
12668
|
+
}
|
|
12395
12669
|
return true;
|
|
12396
12670
|
}
|
|
12671
|
+
raisedOnEntry() {
|
|
12672
|
+
return this.raised;
|
|
12673
|
+
}
|
|
12397
12674
|
deliver() {
|
|
12398
12675
|
if (this.quieted > 0) return;
|
|
12399
12676
|
const killed = Atomics.load(this.header, SAB_I_KILLED);
|
|
@@ -12406,6 +12683,7 @@ var init_process_signals = __esm({
|
|
|
12406
12683
|
const pending = blocked === 0 ? Atomics.exchange(this.header, SAB_I_SIGNALS, 0) : Atomics.and(this.header, SAB_I_SIGNALS, blocked) & ~blocked;
|
|
12407
12684
|
if (this.depth <= 1) this.lastDelivered = pending | (timers & 1 ? sigbit(SIG.ALRM) : 0);
|
|
12408
12685
|
if (pending !== 0 || timers !== 0) this.delivered++;
|
|
12686
|
+
this.raised |= pending | (timers & 1 ? sigbit(SIG.ALRM) : 0) | (timers & ~1 ? -1 : 0);
|
|
12409
12687
|
for (let which = 0; which < 3; which++) {
|
|
12410
12688
|
if (timers & 1 << which) this.hooks.timer?.(which);
|
|
12411
12689
|
}
|
|
@@ -12428,7 +12706,7 @@ function resolved(Fs, addr) {
|
|
|
12428
12706
|
return { family: "unix", path: normalizePath(path) };
|
|
12429
12707
|
}
|
|
12430
12708
|
function createSocketKernel(deps) {
|
|
12431
|
-
const { transport, Fs, sys, streams } = deps;
|
|
12709
|
+
const { transport, Fs, sys, streams: streams2 } = deps;
|
|
12432
12710
|
const call2 = (req) => {
|
|
12433
12711
|
const r = transport.call(req, Number.POSITIVE_INFINITY, req.op);
|
|
12434
12712
|
if (!r.ok) throw new SyscallError(r.errno);
|
|
@@ -12464,12 +12742,12 @@ function createSocketKernel(deps) {
|
|
|
12464
12742
|
const install = (k, nonblock, cloexec = false) => {
|
|
12465
12743
|
let stream;
|
|
12466
12744
|
try {
|
|
12467
|
-
stream =
|
|
12745
|
+
stream = streams2.socketStream(O_RDWR5 | (nonblock ? O_NONBLOCK2 : 0));
|
|
12468
12746
|
} catch (e) {
|
|
12469
12747
|
sys.close(k);
|
|
12470
12748
|
throw e;
|
|
12471
12749
|
}
|
|
12472
|
-
|
|
12750
|
+
streams2.attachSocket(stream, k);
|
|
12473
12751
|
setCloseOnExec(stream, cloexec);
|
|
12474
12752
|
return stream.fd;
|
|
12475
12753
|
};
|
|
@@ -12748,9 +13026,9 @@ function kernelSys(transport) {
|
|
|
12748
13026
|
}
|
|
12749
13027
|
};
|
|
12750
13028
|
}
|
|
12751
|
-
function wireKernelFd(Fs,
|
|
13029
|
+
function wireKernelFd(Fs, streams2, entry) {
|
|
12752
13030
|
if (entry.device && openDevice(Fs, entry.fd, entry.device)) return;
|
|
12753
|
-
placeKernelStream(Fs,
|
|
13031
|
+
placeKernelStream(Fs, streams2, {
|
|
12754
13032
|
...entry,
|
|
12755
13033
|
kind: entry.device ? "stream" : entry.kind,
|
|
12756
13034
|
kernel: entry.fd
|
|
@@ -12775,7 +13053,7 @@ function openAt(Fs, fd, path, flags) {
|
|
|
12775
13053
|
}
|
|
12776
13054
|
return true;
|
|
12777
13055
|
}
|
|
12778
|
-
function wireKernelStdio(Fs,
|
|
13056
|
+
function wireKernelStdio(Fs, streams2, sys) {
|
|
12779
13057
|
for (const fd of [0, 1, 2]) {
|
|
12780
13058
|
const stream = Fs.getStream(fd);
|
|
12781
13059
|
if (!stream) continue;
|
|
@@ -12786,11 +13064,11 @@ function wireKernelStdio(Fs, streams, sys) {
|
|
|
12786
13064
|
const flags = sys?.access ? stream.flags & ~O_ACCMODE5 | accessMode(sys.access(fd)) : stream.flags;
|
|
12787
13065
|
Fs.closeStream(fd);
|
|
12788
13066
|
const kernel = { fd, kernel: fd, kind, flags };
|
|
12789
|
-
placeKernelStream(Fs,
|
|
13067
|
+
placeKernelStream(Fs, streams2, kernel).flags = flags;
|
|
12790
13068
|
continue;
|
|
12791
13069
|
}
|
|
12792
|
-
|
|
12793
|
-
|
|
13070
|
+
streams2.attach(stream, fd);
|
|
13071
|
+
streams2.nameTerminal(stream);
|
|
12794
13072
|
}
|
|
12795
13073
|
}
|
|
12796
13074
|
function glueBody(glue) {
|
|
@@ -12889,6 +13167,11 @@ function credSyncTransport(gated, early, cred) {
|
|
|
12889
13167
|
}
|
|
12890
13168
|
};
|
|
12891
13169
|
}
|
|
13170
|
+
function sigpipeSpared(transport) {
|
|
13171
|
+
const req = { op: "proc-kill-self", sig: SIG.PIPE, probe: true };
|
|
13172
|
+
const r = transport.call(req, Number.POSITIVE_INFINITY, "proc-kill-self");
|
|
13173
|
+
return r.ok && !(r.kind === "json" && r.json === "terminate");
|
|
13174
|
+
}
|
|
12892
13175
|
async function runWasmProcess(init, port3, deps = {}) {
|
|
12893
13176
|
const signals = new SignalGate(
|
|
12894
13177
|
createSyncSabTransport(init.sab, port3, {
|
|
@@ -12996,10 +13279,10 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
12996
13279
|
});
|
|
12997
13280
|
early = () => signals.quiet(() => vfs.flushDirty());
|
|
12998
13281
|
closeDropsLocks(running.FS, sys);
|
|
12999
|
-
const sigpipe = () => running.sliccSigpipe?.() === 1;
|
|
13282
|
+
const sigpipe = () => running.sliccSigpipe?.() === 1 || sigpipeSpared(gated);
|
|
13000
13283
|
const restartable = () => signals.restartable();
|
|
13001
13284
|
const owners = init.owners ? { owners: true } : {};
|
|
13002
|
-
const
|
|
13285
|
+
const streams2 = new KernelStreams(running.FS, sys, {
|
|
13003
13286
|
sigpipe,
|
|
13004
13287
|
restartable,
|
|
13005
13288
|
...owners,
|
|
@@ -13007,21 +13290,21 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
13007
13290
|
});
|
|
13008
13291
|
trackCloseOnExec(running.FS);
|
|
13009
13292
|
quietQuit(running.FS, (on) => {
|
|
13010
|
-
|
|
13293
|
+
streams2.quitting = on;
|
|
13011
13294
|
});
|
|
13012
|
-
atExit = () =>
|
|
13295
|
+
atExit = () => streams2.exiting();
|
|
13013
13296
|
useMounts(running.FS, init.env, true);
|
|
13014
13297
|
useZeroDevices(running.FS);
|
|
13015
13298
|
useProcfs(running.FS, sys, init.pid);
|
|
13016
|
-
if (init.fork) restoreForkedStreams(running.FS,
|
|
13299
|
+
if (init.fork) restoreForkedStreams(running.FS, streams2, init.fork.streams ?? []);
|
|
13017
13300
|
else {
|
|
13018
|
-
wireKernelStdio(running.FS,
|
|
13019
|
-
for (const entry of init.fds ?? []) wireKernelFd(running.FS,
|
|
13301
|
+
wireKernelStdio(running.FS, streams2, sys);
|
|
13302
|
+
for (const entry of init.fds ?? []) wireKernelFd(running.FS, streams2, entry);
|
|
13020
13303
|
}
|
|
13021
13304
|
const pipefs = ownValue(running, "PIPEFS");
|
|
13022
|
-
if (pipefs)
|
|
13023
|
-
|
|
13024
|
-
|
|
13305
|
+
if (pipefs) streams2.usePipes(pipefs);
|
|
13306
|
+
streams2.useControllingTerminal();
|
|
13307
|
+
streams2.useKernelFdMetadata();
|
|
13025
13308
|
useDevFd(running.FS);
|
|
13026
13309
|
useDevRemoval(running.FS);
|
|
13027
13310
|
useFileMmap(running.FS, {
|
|
@@ -13041,9 +13324,9 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
13041
13324
|
restartable,
|
|
13042
13325
|
memory: () => memory,
|
|
13043
13326
|
deliveries: () => signals.deliveries(),
|
|
13044
|
-
describeFork: () => describeForFork(running.FS, sys,
|
|
13045
|
-
inherit: (actions) => describeInherited(running.FS, sys,
|
|
13046
|
-
stdioPromoter: () => vfsPromoter(running.FS, sys,
|
|
13327
|
+
describeFork: () => describeForFork(running.FS, sys, streams2, livePath),
|
|
13328
|
+
inherit: (actions) => describeInherited(running.FS, sys, streams2, livePath, actions),
|
|
13329
|
+
stdioPromoter: () => vfsPromoter(running.FS, sys, streams2, livePath),
|
|
13047
13330
|
...callerOwner(running.FS, init)
|
|
13048
13331
|
});
|
|
13049
13332
|
running.sliccKernel.http = createHttpKernel(transport);
|
|
@@ -13052,15 +13335,15 @@ async function runWasmProcess(init, port3, deps = {}) {
|
|
|
13052
13335
|
transport,
|
|
13053
13336
|
Fs: running.FS,
|
|
13054
13337
|
sys,
|
|
13055
|
-
streams,
|
|
13338
|
+
streams: streams2,
|
|
13056
13339
|
sigpipe,
|
|
13057
13340
|
restartable
|
|
13058
13341
|
});
|
|
13059
|
-
return runWithFlush(running, init,
|
|
13342
|
+
return runWithFlush(running, init, streams2, vfs);
|
|
13060
13343
|
}
|
|
13061
|
-
function runWithFlush(running, init,
|
|
13344
|
+
function runWithFlush(running, init, streams2, vfs) {
|
|
13062
13345
|
try {
|
|
13063
|
-
return
|
|
13346
|
+
return streams2.exitStatus(runMain(running, init));
|
|
13064
13347
|
} finally {
|
|
13065
13348
|
try {
|
|
13066
13349
|
vfs.flush();
|
|
@@ -13312,7 +13595,7 @@ var init_wasi_module = __esm({
|
|
|
13312
13595
|
});
|
|
13313
13596
|
|
|
13314
13597
|
// src/process/wasi/wasi-sigmask.ts
|
|
13315
|
-
var UNBLOCKABLE, LIBC_UNBLOCKABLE, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, kernelBits, libcBits, apply, WasiSigmask;
|
|
13598
|
+
var UNBLOCKABLE, LIBC_UNBLOCKABLE, FOREVER2, NS_PER_MS4, POLL_MS, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK, kernelBits, libcBits, apply, WasiSigmask;
|
|
13316
13599
|
var init_wasi_sigmask = __esm({
|
|
13317
13600
|
"src/process/wasi/wasi-sigmask.ts"() {
|
|
13318
13601
|
"use strict";
|
|
@@ -13321,6 +13604,9 @@ var init_wasi_sigmask = __esm({
|
|
|
13321
13604
|
init_wasi_abi();
|
|
13322
13605
|
UNBLOCKABLE = sigbit(SIG.KILL) | sigbit(SIG.STOP);
|
|
13323
13606
|
LIBC_UNBLOCKABLE = 1 << SIG.KILL - 1 | 1 << SIG.STOP - 1;
|
|
13607
|
+
FOREVER2 = 0xffffffffffffffffn;
|
|
13608
|
+
NS_PER_MS4 = 1000000n;
|
|
13609
|
+
POLL_MS = 50;
|
|
13324
13610
|
SIG_BLOCK = 0;
|
|
13325
13611
|
SIG_UNBLOCK = 1;
|
|
13326
13612
|
SIG_SETMASK = 2;
|
|
@@ -13337,10 +13623,12 @@ var init_wasi_sigmask = __esm({
|
|
|
13337
13623
|
header;
|
|
13338
13624
|
deliver;
|
|
13339
13625
|
process;
|
|
13340
|
-
|
|
13626
|
+
tid;
|
|
13627
|
+
constructor(header, deliver, process, tid = 1) {
|
|
13341
13628
|
this.header = header;
|
|
13342
13629
|
this.deliver = deliver;
|
|
13343
13630
|
this.process = process;
|
|
13631
|
+
this.tid = tid;
|
|
13344
13632
|
this.lo = libcBits(Atomics.load(header, SAB_I_BLOCKED));
|
|
13345
13633
|
this.hi = Atomics.load(header, SAB_I_BLOCKED_HI);
|
|
13346
13634
|
}
|
|
@@ -13374,6 +13662,12 @@ var init_wasi_sigmask = __esm({
|
|
|
13374
13662
|
this.set(SIG_SETMASK, lo, hi, () => {
|
|
13375
13663
|
});
|
|
13376
13664
|
}
|
|
13665
|
+
blockedBits() {
|
|
13666
|
+
return Atomics.load(this.header, SAB_I_BLOCKED);
|
|
13667
|
+
}
|
|
13668
|
+
blocks(sig) {
|
|
13669
|
+
return (Atomics.load(this.header, SAB_I_BLOCKED) & sigbit(sig)) !== 0;
|
|
13670
|
+
}
|
|
13377
13671
|
inherited() {
|
|
13378
13672
|
return [kernelBits(this.lo), this.hi];
|
|
13379
13673
|
}
|
|
@@ -13381,6 +13675,47 @@ var init_wasi_sigmask = __esm({
|
|
|
13381
13675
|
Atomics.and(this.header, SAB_I_SIGNALS, ~sigbit(sig));
|
|
13382
13676
|
if (this.process) Atomics.and(this.process, SAB_I_SIGNALS, ~sigbit(sig));
|
|
13383
13677
|
}
|
|
13678
|
+
sigwait(setLo, timeoutNs, publish, took, entered = false) {
|
|
13679
|
+
const set = kernelBits(setLo | 0);
|
|
13680
|
+
const value2 = BigInt.asUintN(64, timeoutNs);
|
|
13681
|
+
const deadline = value2 === FOREVER2 ? Number.POSITIVE_INFINITY : performance.now() + Number((value2 + NS_PER_MS4 - 1n) / NS_PER_MS4);
|
|
13682
|
+
publish(set);
|
|
13683
|
+
try {
|
|
13684
|
+
for (; ; ) {
|
|
13685
|
+
const seen = Atomics.load(this.header, SAB_I_SIGNALS);
|
|
13686
|
+
const sig = this.take(set);
|
|
13687
|
+
if (sig !== 0) {
|
|
13688
|
+
took(sig);
|
|
13689
|
+
return E.SUCCESS;
|
|
13690
|
+
}
|
|
13691
|
+
if (entered || this.deliverUnblocked() || this.interrupted()) return E.INTR;
|
|
13692
|
+
const left = deadline - performance.now();
|
|
13693
|
+
if (left <= 0) return E.AGAIN;
|
|
13694
|
+
Atomics.wait(this.header, SAB_I_SIGNALS, seen, Math.min(left, POLL_MS));
|
|
13695
|
+
}
|
|
13696
|
+
} finally {
|
|
13697
|
+
publish(0);
|
|
13698
|
+
}
|
|
13699
|
+
}
|
|
13700
|
+
take(set) {
|
|
13701
|
+
for (const header of this.process ? [this.header, this.process] : [this.header]) {
|
|
13702
|
+
const ready = Atomics.load(header, SAB_I_SIGNALS) & set;
|
|
13703
|
+
if (ready === 0) continue;
|
|
13704
|
+
const bit = ready & -ready;
|
|
13705
|
+
if ((Atomics.and(header, SAB_I_SIGNALS, ~bit) & bit) !== 0) return 31 - Math.clz32(bit);
|
|
13706
|
+
}
|
|
13707
|
+
return 0;
|
|
13708
|
+
}
|
|
13709
|
+
interrupted() {
|
|
13710
|
+
const killed = this.process ?? this.header;
|
|
13711
|
+
if (Atomics.load(killed, SAB_I_KILLED) !== 0) {
|
|
13712
|
+
this.deliver();
|
|
13713
|
+
return true;
|
|
13714
|
+
}
|
|
13715
|
+
if (Atomics.load(killed, SAB_I_STOP) !== 1) return false;
|
|
13716
|
+
while (Atomics.load(killed, SAB_I_STOP) === 1) Atomics.wait(killed, SAB_I_STOP, 1);
|
|
13717
|
+
return true;
|
|
13718
|
+
}
|
|
13384
13719
|
pending() {
|
|
13385
13720
|
const own = Atomics.load(this.header, SAB_I_SIGNALS);
|
|
13386
13721
|
return libcBits(own | (this.process ? Atomics.load(this.process, SAB_I_SIGNALS) : 0));
|
|
@@ -13739,91 +14074,6 @@ var init_wasix_fork = __esm({
|
|
|
13739
14074
|
}
|
|
13740
14075
|
});
|
|
13741
14076
|
|
|
13742
|
-
// src/process/wasi/wasix-epoll.ts
|
|
13743
|
-
function timeoutMs(ns) {
|
|
13744
|
-
const value2 = BigInt.asUintN(64, ns);
|
|
13745
|
-
if (value2 === FOREVER) return -1;
|
|
13746
|
-
const ms = (value2 + NS_PER_MS3 - 1n) / NS_PER_MS3;
|
|
13747
|
-
return ms > BigInt(MAX_TIMEOUT_MS) ? -1 : Number(ms);
|
|
13748
|
-
}
|
|
13749
|
-
function wasixEpollImports(host) {
|
|
13750
|
-
const { mem, fds, o } = host;
|
|
13751
|
-
const call2 = (req) => o.kernel.call(req);
|
|
13752
|
-
const kernelFd = (fd, refusal2) => {
|
|
13753
|
-
const e = fds.find(fd);
|
|
13754
|
-
if (!e) throw new WasiError("EBADF");
|
|
13755
|
-
if (e.type !== "kernel") throw new WasiError(refusal2);
|
|
13756
|
-
};
|
|
13757
|
-
const writeEvents2 = (ptr, events) => {
|
|
13758
|
-
const view = mem.view();
|
|
13759
|
-
events.forEach((ev, i) => {
|
|
13760
|
-
const at = ptr + i * EVENT_SIZE;
|
|
13761
|
-
mem.bytes(at, EVENT_SIZE).fill(0);
|
|
13762
|
-
view.setUint32(at, ev.events, true);
|
|
13763
|
-
mem.bytes(at + DATA_OFFSET, DATA_SIZE).set(ev.data);
|
|
13764
|
-
});
|
|
13765
|
-
};
|
|
13766
|
-
return {
|
|
13767
|
-
epoll_create: (out) => {
|
|
13768
|
-
const fd = call2({ op: "epoll-create" });
|
|
13769
|
-
fds.adopt(fd, "stream", false);
|
|
13770
|
-
mem.view().setUint32(out, fd, true);
|
|
13771
|
-
},
|
|
13772
|
-
epoll_ctl: (epfd, op, fd, event) => {
|
|
13773
|
-
const how = OPS[op];
|
|
13774
|
-
if (!how) throw new WasiError("EINVAL");
|
|
13775
|
-
kernelFd(epfd, "EINVAL");
|
|
13776
|
-
kernelFd(fd, "EPERM");
|
|
13777
|
-
if (how !== "del" && event === 0) throw new WasiError("EINVAL");
|
|
13778
|
-
const events = event === 0 ? 0 : mem.view().getUint32(event, true);
|
|
13779
|
-
const data = event === 0 ? [] : [...mem.bytes(event + DATA_OFFSET, DATA_SIZE)];
|
|
13780
|
-
call2({ op: "epoll-ctl", epfd, how, fd, events, data });
|
|
13781
|
-
},
|
|
13782
|
-
epoll_wait: (epfd, ptr, maxevents, timeout, out) => {
|
|
13783
|
-
mem.view().setUint32(out, 0, true);
|
|
13784
|
-
if ((maxevents | 0) <= 0) throw new WasiError("EINVAL");
|
|
13785
|
-
kernelFd(epfd, "EINVAL");
|
|
13786
|
-
const max = Math.min(maxevents | 0, MAX_EVENTS);
|
|
13787
|
-
const ms = host.entered ? 0 : timeoutMs(timeout);
|
|
13788
|
-
const events = call2({ op: "epoll-wait", epfd, max, timeoutMs: ms });
|
|
13789
|
-
if (host.entered && events.length === 0 && timeoutMs(timeout) !== 0) return E.INTR;
|
|
13790
|
-
writeEvents2(ptr, events);
|
|
13791
|
-
mem.view().setUint32(out, events.length, true);
|
|
13792
|
-
return E.SUCCESS;
|
|
13793
|
-
},
|
|
13794
|
-
fd_event: (initial, flags, out) => {
|
|
13795
|
-
const value2 = BigInt.asUintN(64, initial);
|
|
13796
|
-
if (value2 > EVENTFD_MAX) throw new WasiError("EINVAL");
|
|
13797
|
-
const fd = call2({
|
|
13798
|
-
op: "eventfd-open",
|
|
13799
|
-
initial: value2.toString(),
|
|
13800
|
-
semaphore: (flags & EVENTFD_SEMAPHORE) !== 0
|
|
13801
|
-
});
|
|
13802
|
-
fds.adopt(fd, "stream", (flags & EVENTFD_NONBLOCK) !== 0);
|
|
13803
|
-
mem.view().setUint32(out, fd, true);
|
|
13804
|
-
}
|
|
13805
|
-
};
|
|
13806
|
-
}
|
|
13807
|
-
var EVENT_SIZE, DATA_OFFSET, DATA_SIZE, MAX_EVENTS, FOREVER, MAX_TIMEOUT_MS, NS_PER_MS3, EVENTFD_SEMAPHORE, EVENTFD_NONBLOCK, EVENTFD_MAX, OPS;
|
|
13808
|
-
var init_wasix_epoll = __esm({
|
|
13809
|
-
"src/process/wasi/wasix-epoll.ts"() {
|
|
13810
|
-
"use strict";
|
|
13811
|
-
init_wasi_abi();
|
|
13812
|
-
init_wasi_files();
|
|
13813
|
-
EVENT_SIZE = 32;
|
|
13814
|
-
DATA_OFFSET = 8;
|
|
13815
|
-
DATA_SIZE = 24;
|
|
13816
|
-
MAX_EVENTS = 4096;
|
|
13817
|
-
FOREVER = 0xffffffffffffffffn;
|
|
13818
|
-
MAX_TIMEOUT_MS = 2147483647;
|
|
13819
|
-
NS_PER_MS3 = 1000000n;
|
|
13820
|
-
EVENTFD_SEMAPHORE = 1;
|
|
13821
|
-
EVENTFD_NONBLOCK = 4;
|
|
13822
|
-
EVENTFD_MAX = 0xfffffffffffffffen;
|
|
13823
|
-
OPS = ["add", "set", "del", "mod"];
|
|
13824
|
-
}
|
|
13825
|
-
});
|
|
13826
|
-
|
|
13827
14077
|
// src/process/wasi/wasix-ffi.ts
|
|
13828
14078
|
function read(view, at, type) {
|
|
13829
14079
|
if (type === "i32") return view.getInt32(at, true);
|
|
@@ -14730,7 +14980,7 @@ function posixSignal(sig) {
|
|
|
14730
14980
|
function nsToMs(ns) {
|
|
14731
14981
|
return Math.ceil(Number(ns) / 1e6);
|
|
14732
14982
|
}
|
|
14733
|
-
var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON2, ECHO2, FUTEX_SLICE_MS, EINTR_LIBC, MAIN_HANDLE, WasixHost;
|
|
14983
|
+
var FDFLAGSEXT_CLOEXEC, SPAWN_OP_SIZE, SPAWN_OPS, RIGHTS_FD_WRITE, ICANON2, ECHO2, FUTEX_SLICE_MS, EINTR_LIBC, STRICT_EPOLL_LIBC, MAIN_HANDLE, WasixHost;
|
|
14734
14984
|
var init_wasix_host = __esm({
|
|
14735
14985
|
"src/process/wasi/wasix-host.ts"() {
|
|
14736
14986
|
"use strict";
|
|
@@ -14754,6 +15004,7 @@ var init_wasix_host = __esm({
|
|
|
14754
15004
|
ECHO2 = 8;
|
|
14755
15005
|
FUTEX_SLICE_MS = 50;
|
|
14756
15006
|
EINTR_LIBC = 22;
|
|
15007
|
+
STRICT_EPOLL_LIBC = 29;
|
|
14757
15008
|
MAIN_HANDLE = 2147483647;
|
|
14758
15009
|
WasixHost = class _WasixHost {
|
|
14759
15010
|
process;
|
|
@@ -14772,6 +15023,7 @@ var init_wasix_host = __esm({
|
|
|
14772
15023
|
driver,
|
|
14773
15024
|
() => (this.threads?.tid ?? MAIN_TID) !== MAIN_TID
|
|
14774
15025
|
);
|
|
15026
|
+
if (module) host.strictEpoll = (libcVersion(module) ?? 0) >= STRICT_EPOLL_LIBC;
|
|
14775
15027
|
if (module && !WebAssembly.Module.imports(module).some((i) => i.name === "fd_fdflags_set")) {
|
|
14776
15028
|
host.fds.implicitCloexec = true;
|
|
14777
15029
|
host.interruptWakes = (libcVersion(module) ?? 0) < EINTR_LIBC;
|
|
@@ -15232,6 +15484,7 @@ __export(wasi_runtime_exports, {
|
|
|
15232
15484
|
});
|
|
15233
15485
|
function wireSignals(host, gate) {
|
|
15234
15486
|
host.interrupted = () => gate.interrupt();
|
|
15487
|
+
host.raisedOnEntry = () => gate.raisedOnEntry();
|
|
15235
15488
|
host.quietly = (fn) => gate.quiet(fn);
|
|
15236
15489
|
}
|
|
15237
15490
|
function catchUpFirst(host, sync) {
|
|
@@ -15257,6 +15510,7 @@ function delivering(ns, table, host, driver, before) {
|
|
|
15257
15510
|
if (driver.idle) {
|
|
15258
15511
|
before?.();
|
|
15259
15512
|
host.entered = host.interrupted?.() === true;
|
|
15513
|
+
host.enteredSignals = host.entered ? host.raisedOnEntry?.() ?? -1 : 0;
|
|
15260
15514
|
}
|
|
15261
15515
|
return fn(...args);
|
|
15262
15516
|
};
|
|
@@ -15271,7 +15525,7 @@ function sigmaskOf(module, sab, gate, threads, process) {
|
|
|
15271
15525
|
}
|
|
15272
15526
|
if (threads) threads.blocked = () => loadBlocked(header);
|
|
15273
15527
|
const shared = process && new Int32Array(process, 0, SAB_HEADER_I32);
|
|
15274
|
-
return new WasiSigmask(header, () => gate.deliver(), shared);
|
|
15528
|
+
return new WasiSigmask(header, () => gate.deliver(), shared, threads?.tid ?? MAIN_TID);
|
|
15275
15529
|
}
|
|
15276
15530
|
function enosys(module, name2, foreign) {
|
|
15277
15531
|
const type = foreign?.[module]?.[name2];
|
|
@@ -15625,7 +15879,8 @@ async function runWasiProcess(init, port3) {
|
|
|
15625
15879
|
),
|
|
15626
15880
|
procTree(call2, id.pid)
|
|
15627
15881
|
),
|
|
15628
|
-
...descriptors(init, fork, threads)
|
|
15882
|
+
...descriptors(init, fork, threads),
|
|
15883
|
+
...threads ? { credGen: threads.ids } : {}
|
|
15629
15884
|
});
|
|
15630
15885
|
host.sigmask = sigmaskOf(module, init.sab, gate, threads);
|
|
15631
15886
|
if (threads) {
|