@ai-ecoverse/slicc-kernel 1.145.1 → 1.146.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 +1 -1
- package/dist/kernel-worker.js +1 -1
- package/dist/node-process-worker.js +34 -14
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +1 -1
- package/dist/process-worker.js +34 -14
- package/dist/process-worker.js.map +2 -2
- package/dist/types/process/js/js-net.d.ts +7 -1
- package/dist/types/process/js/js-sync.d.ts +3 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -448,7 +448,7 @@ The module's default export (or its `main` export) is called with a context and
|
|
|
448
448
|
- `wait(pid, { untraced })` resolves with `{ status }` once a child ends, or `{ status: 128 + signal, signal }` when a signal ended it, without blocking the program; with `untraced: true` it also resolves when the child stops, with `{ status: 128 + signal, signal, stopped: true }`, as `waitpid` with `WUNTRACED` (a child's `wait({ untraced })` is the same), and options that aren't an object are `EINVAL`; `kill(pid, signal)` signals any process, by number or as `'SIGTERM'` (the default);
|
|
449
449
|
- `sudo(args)`, what the [`sudo`](#sudo) command calls: `args` are its arguments after `sudo`, and it resolves with `{ pid }`, the command the kernel started as the program's child, to `wait` for; `{ run }`, an argv to run as the caller (with `users: 'off'`); `{ list }`, the text of `sudo -l`; or `{ error, errno }`, the message to print;
|
|
450
450
|
- `crontab({ action, user?, text? })`, what the [`crontab`](#cron) command calls: `action` is `'list'`, `'remove'` or `'install'` (with the table as `text`), on the caller's own table or, for an effective uid of 0, on `user`'s. It resolves with `{ text }` (the table for `list`, `''` otherwise) or `{ error }`, the message to print. A malformed call is `EINVAL`;
|
|
451
|
-
- `net`: `listen({ port, host, backlog })` and `connect({ host, port, signal })` (`host` defaults to `127.0.0.1`) on the kernel's loopback, the same sockets WASIX programs use, so a JS server is reached by other processes, by the page as `<port>.kernel.localhost` (`loopbackFetch`, `dial`) and by attached clients. A listener has its `port` (as bound, so port `0` picks a free one), `accept({ signal })`, `close()` and `for await` over its connections. A connection has `local` and `remote` addresses, `readable` and `writable` web streams (closing the writable shuts down the sending side, so the peer reads the end), and `close()`. The loopback is IPv4 (`127.0.0.1` by default, or `0.0.0.0`), so an IPv6 host such as `::1` fails with `EADDRNOTAVAIL` for both `listen` and `connect`, and binding and connecting fail as they would for a WASIX program (`EADDRINUSE`, `ECONNREFUSED`, `EADDRNOTAVAIL`). A blocked accept, read or write waits without holding anything in the kernel, so aborting it or closing the socket leaves nothing behind. A write to a connection the peer closed fails with `EPIPE` and no `SIGPIPE`;
|
|
451
|
+
- `net`: `listen({ port, host, backlog })` and `connect({ host, port, signal })` (`host` defaults to `127.0.0.1`) on the kernel's loopback, the same sockets WASIX programs use, so a JS server is reached by other processes, by the page as `<port>.kernel.localhost` (`loopbackFetch`, `dial`) and by attached clients. A listener has its `port` (as bound, so port `0` picks a free one), `accept({ signal })`, `close()` and `for await` over its connections. A connection has `local` and `remote` addresses, `readable` and `writable` web streams (closing the writable shuts down the sending side, so the peer reads the end), and `close()`. The loopback is IPv4 (`127.0.0.1` by default, or `0.0.0.0`), so an IPv6 host such as `::1` fails with `EADDRNOTAVAIL` for both `listen` and `connect`, and binding and connecting fail as they would for a WASIX program (`EADDRINUSE`, `ECONNREFUSED`, `EADDRNOTAVAIL`). `sync.net.listen` takes the same options and gives the same listener, bound and listening when it returns, so its `port` is known at once, as Node's `listen()` needs ([#1398](https://github.com/ai-ecoverse/slicc-kernel/issues/1398)); it needs the sync lane. A blocked accept, read or write waits without holding anything in the kernel, so aborting it or closing the socket leaves nothing behind. A write to a connection the peer closed fails with `EPIPE` and no `SIGPIPE`;
|
|
452
452
|
- `net.connect({ host, port, tls: { servername, alpn, rejectUnauthorized, ca, path, cert, key, passphrase, sni, checkHostname } })` takes one of two paths. By default it's **A1, TLS through the transport** ([#914](https://github.com/ai-ecoverse/slicc-kernel/issues/914)), described first below. For a destination the uplink routes it can also be **A2, a TLS handshake in the kernel** ([#922](https://github.com/ai-ecoverse/slicc-kernel/issues/922)), described after it. `conn.tls.path` (`'transport'` or `'kernel'`) and `conn.tls.substitutes` say which one was taken.
|
|
453
453
|
- **What it does:** there's no handshake in the kernel. The connection carries plain HTTP/1.1 (and WebSocket upgrades) to the realm proxy's HTTP path for the origin `https://<servername or host>[:port]`, exactly as a `CONNECT` through `127.0.0.1:3128` does after the kernel terminates its TLS. The transport (the page's `fetch` or WebSocket, or the uplink's) makes the real TLS connection and verifies it. So `https.request` over a socket, keep-alive agents, `agent-base` and `wss://` clients work with the transport's semantics. That includes sealed placeholders in headers, which reach the transport exactly as from `ctx.fetch`.
|
|
454
454
|
- **The `tls` property:** the connection's `tls` is `{ path: 'transport', substitutes: true, protocol: 'transport', alpnProtocol: 'http/1.1', authorized: true, servername }`. `authorized` means the transport verified the server. There's no peer certificate chain and no TLS version of the kernel's own, so don't read it as a real handshake's result.
|
package/dist/kernel-worker.js
CHANGED
|
@@ -7728,7 +7728,7 @@ function satisfies(version, range2) {
|
|
|
7728
7728
|
}
|
|
7729
7729
|
|
|
7730
7730
|
// src/version.ts
|
|
7731
|
-
var KERNEL_VERSION = true ? "1.
|
|
7731
|
+
var KERNEL_VERSION = true ? "1.146.0" : "0.0.0-dev";
|
|
7732
7732
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7733
7733
|
function procVersion() {
|
|
7734
7734
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -6800,7 +6800,7 @@ var KERNEL_VERSION, OS_RELEASE;
|
|
|
6800
6800
|
var init_version = __esm({
|
|
6801
6801
|
"src/version.ts"() {
|
|
6802
6802
|
"use strict";
|
|
6803
|
-
KERNEL_VERSION = true ? "1.
|
|
6803
|
+
KERNEL_VERSION = true ? "1.146.0" : "0.0.0-dev";
|
|
6804
6804
|
OS_RELEASE = "6.0.0-slicc";
|
|
6805
6805
|
}
|
|
6806
6806
|
});
|
|
@@ -7715,7 +7715,7 @@ function port(n) {
|
|
|
7715
7715
|
if (!Number.isInteger(n) || n < 0 || n > 65535) throw new JsCallError("EINVAL", `port ${n}`);
|
|
7716
7716
|
return n;
|
|
7717
7717
|
}
|
|
7718
|
-
function netOps(kernel, io) {
|
|
7718
|
+
function netOps(kernel, io, sync) {
|
|
7719
7719
|
const name2 = async (fd, peer) => addressOf(await kernel.json({ op: "sock-name", fd, peer }));
|
|
7720
7720
|
const connection = async (fd) => {
|
|
7721
7721
|
const [local3, remote] = [await name2(fd, false), await name2(fd, true)];
|
|
@@ -7830,14 +7830,29 @@ function netOps(kernel, io) {
|
|
|
7830
7830
|
});
|
|
7831
7831
|
return [...r.ok && r.kind === "json" ? r.json : []];
|
|
7832
7832
|
};
|
|
7833
|
+
const inetAt = (options) => ({
|
|
7834
|
+
family: "inet",
|
|
7835
|
+
host: options.host ?? "127.0.0.1",
|
|
7836
|
+
port: port(options.port ?? 0)
|
|
7837
|
+
});
|
|
7838
|
+
const listenSync = (options = {}) => {
|
|
7839
|
+
const lane = sync;
|
|
7840
|
+
const addr = inetAt(options);
|
|
7841
|
+
const fd = lane.json({ op: "sock-open", domain: "inet" });
|
|
7842
|
+
try {
|
|
7843
|
+
lane.call({ op: "sock-bind", fd, addr });
|
|
7844
|
+
lane.call({ op: "sock-listen", fd, backlog: options.backlog ?? 128 });
|
|
7845
|
+
return listener(fd, addressOf(lane.json({ op: "sock-name", fd, peer: false })));
|
|
7846
|
+
} catch (err) {
|
|
7847
|
+
lane.raw({ op: "fd-close", fd });
|
|
7848
|
+
throw err;
|
|
7849
|
+
}
|
|
7850
|
+
};
|
|
7833
7851
|
return {
|
|
7852
|
+
sync: { listen: listenSync },
|
|
7834
7853
|
resolve: lookup2,
|
|
7835
7854
|
listen: (options = {}) => opened2(async (fd) => {
|
|
7836
|
-
const addr =
|
|
7837
|
-
family: "inet",
|
|
7838
|
-
host: options.host ?? "127.0.0.1",
|
|
7839
|
-
port: port(options.port ?? 0)
|
|
7840
|
-
};
|
|
7855
|
+
const addr = inetAt(options);
|
|
7841
7856
|
await kernel.call({ op: "sock-bind", fd, addr });
|
|
7842
7857
|
await kernel.call({ op: "sock-listen", fd, backlog: options.backlog ?? 128 });
|
|
7843
7858
|
return listener(fd, await name2(fd, false));
|
|
@@ -15393,6 +15408,14 @@ async function vfsOpen(kernel, abs, options, statOf, io, whole) {
|
|
|
15393
15408
|
handles.set(fd, handle.invalidate);
|
|
15394
15409
|
return handle.file;
|
|
15395
15410
|
}
|
|
15411
|
+
function setcredOn(syncKernel) {
|
|
15412
|
+
return (change) => {
|
|
15413
|
+
if (typeof change !== "object" || change === null || Array.isArray(change)) {
|
|
15414
|
+
throw new JsCallError("EINVAL", "setcred");
|
|
15415
|
+
}
|
|
15416
|
+
return syncKernel.json({ op: "proc-setcred", change: { ...change } });
|
|
15417
|
+
};
|
|
15418
|
+
}
|
|
15396
15419
|
function watchingSyncOps(kernel, syncKernel, shared) {
|
|
15397
15420
|
const ops = syncOps(syncKernel, shared);
|
|
15398
15421
|
const watch = (path, options, listener) => {
|
|
@@ -15537,6 +15560,7 @@ function createContext(o) {
|
|
|
15537
15560
|
run: (options) => runSync(syncKernel, { env: o.env, cwd: o.cwd, resolve: resolve2, signal: signalNumber }, options),
|
|
15538
15561
|
spawn: (options) => spawnSync(options),
|
|
15539
15562
|
wasi: { create: wasi.create },
|
|
15563
|
+
net: { listen: (options) => syncNet.listen(options) },
|
|
15540
15564
|
exit: (status2 = 0) => {
|
|
15541
15565
|
exiting ??= status2 & 255;
|
|
15542
15566
|
wasi.closeAll();
|
|
@@ -15545,16 +15569,12 @@ function createContext(o) {
|
|
|
15545
15569
|
kill: killer({ self: o.pid, kernel, syncKernel, lane, writes, modes: terminal.modes }),
|
|
15546
15570
|
cred: () => syncKernel.json({ op: "proc-cred" }),
|
|
15547
15571
|
umask: (mask) => syncKernel.json(umaskRequest(mask)),
|
|
15548
|
-
setcred(
|
|
15549
|
-
if (typeof change !== "object" || change === null || Array.isArray(change)) {
|
|
15550
|
-
throw new JsCallError("EINVAL", "setcred");
|
|
15551
|
-
}
|
|
15552
|
-
return syncKernel.json({ op: "proc-setcred", change: { ...change } });
|
|
15553
|
-
}
|
|
15572
|
+
setcred: setcredOn(syncKernel)
|
|
15554
15573
|
};
|
|
15555
15574
|
const io = { read: read2, send: writeAll, close: (fd) => ctx.close(fd) };
|
|
15556
15575
|
const defaults = { env: o.env, cwd: o.cwd, signal: signalNumber };
|
|
15557
15576
|
const { spawnSync, ...children } = childOps(kernel, io, defaults, syncKernel);
|
|
15577
|
+
const { sync: syncNet, ...net } = netOps(kernel, io, syncKernel);
|
|
15558
15578
|
const strays = o.strays ?? { exception: /* @__PURE__ */ new Set(), rejection: /* @__PURE__ */ new Set() };
|
|
15559
15579
|
const ctx = {
|
|
15560
15580
|
kernel: KERNEL_INFO,
|
|
@@ -15602,7 +15622,7 @@ function createContext(o) {
|
|
|
15602
15622
|
}),
|
|
15603
15623
|
crontab: async (call2) => await kernel.json({ ...call2, op: "proc-crontab" }),
|
|
15604
15624
|
...children,
|
|
15605
|
-
net
|
|
15625
|
+
net,
|
|
15606
15626
|
websocket: websocketOp(kernel),
|
|
15607
15627
|
tty: terminal.tty,
|
|
15608
15628
|
exit,
|