@amritk/nish-x86_64-linux 0.24.0 → 0.26.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/bin/nish +0 -0
- package/docs/AI.md +45 -4
- package/package.json +1 -1
- package/runtime/browser.mjs +4 -3
- package/runtime/core/host.d.ts +12 -0
- package/runtime/core/host.mjs +74 -2
- package/runtime/nish.d.ts +148 -0
- package/runtime/nish.h +59 -0
- package/runtime/nish.mjs +25 -0
- package/runtime/node.mjs +136 -6
- package/runtime/runtime-net.c +44 -3
- package/runtime/runtime-os.c +351 -18
- package/scripts/build.sh +13 -3
- package/std/README.md +27 -10
- package/std/cli-args.ts +1216 -0
- package/std/cli-flags.ts +585 -0
- package/std/cli.ts +308 -19
- package/std/compress/checksum.ts +132 -20
- package/std/compress/deflate.ts +638 -248
- package/std/compress/gzip.ts +20 -6
- package/std/crypto/LICENSE-fiat-crypto-p384 +21 -0
- package/std/crypto/p256.ts +63 -1
- package/std/crypto/p384.ts +6044 -0
- package/std/crypto/pki-roots.ts +322 -0
- package/std/crypto/pki.ts +1207 -0
- package/std/crypto/rsa.ts +663 -0
- package/std/crypto/x509.ts +1054 -58
- package/std/net/dns-config.ts +734 -0
- package/std/net/dns-message.ts +517 -0
- package/std/net/dns-resolver.ts +1015 -0
- package/std/net/dns.ts +478 -0
- package/std/net/http1-client.ts +1227 -0
- package/std/net/http1-server.ts +7 -2
- package/std/net/http1.ts +9 -9
- package/std/net/postgres.ts +259 -26
- package/std/net/tls/client.ts +1094 -0
- package/std/net/tls/codec.ts +585 -3
- package/std/net/tls/record-client.ts +1192 -0
- package/std/net/tls/verify.ts +221 -0
- package/std/net/tls-tcp.ts +642 -11
- package/std/net/tls.ts +2 -2
- package/std/net/url.ts +559 -4
- package/std/yaml-write.ts +415 -0
package/bin/nish
CHANGED
|
Binary file
|
package/docs/AI.md
CHANGED
|
@@ -2133,13 +2133,27 @@ a `\u` escape `nish/json` decodes) is one unit per byte, and counts its bytes.
|
|
|
2133
2133
|
**Files and the system.** `readFileSync(path)` (exits 1 on failure),
|
|
2134
2134
|
`readFileSyncOrNull(path)` (`string | null`), `readFileBytesSync(path)`
|
|
2135
2135
|
(`u8[] | null`, the bytes as they are on disk), `writeFileSync(path, data)`,
|
|
2136
|
-
`appendFileSync(path, data)`, `
|
|
2136
|
+
`appendFileSync(path, data)`, `writeFileBytesSync(path, bytes)` (a `u8[]` as
|
|
2137
|
+
it is; `i32`: the length, or a negative errno), `renameSync(from, to)` (`0` or
|
|
2138
|
+
a negative errno; atomic on one filesystem, `-18` across two, so write the
|
|
2139
|
+
temporary beside the target), `unlinkSync(path)` (`0` or a negative errno; a
|
|
2140
|
+
directory is refused), `writeFileSyncMode(path, data, mode)` (the file left
|
|
2141
|
+
at exactly `mode` (`0..0o777`), set before the first byte, written in place; a symbolic link refused; the
|
|
2142
|
+
length or a negative errno), `createFileExclusiveSync(path, data, mode)` (the
|
|
2143
|
+
same, but `-17` when the name exists: a lock file), `mkdirSyncMode(path, mode)`
|
|
2144
|
+
(`0`, `-17` when it exists, the umask applies), `writeBytes(bytes, off, len)` (a `u8[]` range to stdout
|
|
2145
|
+
as it is, the length or a negative errno; the range panics like
|
|
2146
|
+
`netWrite`'s), `mkdirSync(path)` (one level, `boolean`),
|
|
2137
2147
|
`isDirectorySync(path)`, `readdirSync(path)` (`string[] | null`, sorted by
|
|
2138
2148
|
bytes, no `.`/`..`), `spawnSync(argv)`, `spawnSyncTo(argv, outPath, errPath)`,
|
|
2149
|
+
`spawnPiped(argv, stdin, stdout, stderr)` (stdin from a `u8[]`, both outputs
|
|
2150
|
+
appended to `u8[]`s, the status; `-2` past 16 MiB; the way to hand a child a
|
|
2151
|
+
secret, never argv or the environment),
|
|
2139
2152
|
`getenv(name)` (`string | null` — unset and empty are different answers),
|
|
2140
2153
|
`realpathSync(path)` (`string | null`; symbolic links resolved, absolute, and
|
|
2141
2154
|
`null` when it does not resolve),
|
|
2142
|
-
`monotonicNanos()` (`i64`; elapsed time only),
|
|
2155
|
+
`monotonicNanos()` (`i64`; elapsed time only), `wallClockNanos()` (`i64`,
|
|
2156
|
+
nanoseconds since the Unix epoch; the wall clock, which can step), and, for checking a path before
|
|
2143
2157
|
trusting it, `lstatOwnerModeSync(path)` (an `i64`: the owner's uid in the high
|
|
2144
2158
|
32 bits, `st_mode` in the low 32, `-1` when it does not resolve; a symbolic
|
|
2145
2159
|
link answers for itself), `geteuid()` (`i64`) and `isExecutableSync(path)`
|
|
@@ -2167,6 +2181,12 @@ also watches the signal fd. None of `spawn`, `kill`, `waitPid` may be called in
|
|
|
2167
2181
|
a task or a parallel body; the two host facts may. `availableParallelism()` (`i32`, at least 1, no `--threads` needed) and
|
|
2168
2182
|
`totalMemory()` (`i64` bytes, or `-1`) size a program to the machine. None of
|
|
2169
2183
|
the five exists on a wasm target, and `spawn` and `waitPid` throw under Node.
|
|
2184
|
+
`setNice(n)` sets the nice value (clamped to -20..19; lowering it unprivileged
|
|
2185
|
+
is `-13`) and `setIdlePriority()` moves the program to Linux's `SCHED_IDLE`
|
|
2186
|
+
(`-95` on Darwin); each answers 0 or a negative errno. Call them at the top of
|
|
2187
|
+
`main`, never in a task. An unprivileged process can never leave `SCHED_IDLE`
|
|
2188
|
+
and an idle one can starve on a saturated machine, so keep a normal-priority
|
|
2189
|
+
fallback. Neither exists on wasm; both throw under Node.
|
|
2170
2190
|
|
|
2171
2191
|
**Sockets** (`nish:net`, or the same names as globals). `tcpListen(host, port,
|
|
2172
2192
|
backlog)`, `tcpAccept(fd, peer)`, `netRead(fd, buf, off, len)`,
|
|
@@ -2179,7 +2199,8 @@ and there is no `async` and no callback: your `main` is the loop. A client calls
|
|
|
2179
2199
|
`tcpConnect(addr)`, which answers the descriptor while it is still connecting;
|
|
2180
2200
|
wait for it to be writable, then `connectResult(fd)` is 0 or the failure. Buffers
|
|
2181
2201
|
are `u8[]` only; an address is 18 bytes of one (IPv4 as `::ffff:a.b.c.d`, then
|
|
2182
|
-
the port big-endian); hosts are numeric literals,
|
|
2202
|
+
the port big-endian); hosts are numeric literals; to reach a name, resolve it first with
|
|
2203
|
+
`nish/net/dns` (`DnsClient` on your loop, or the blocking `resolveHost`).
|
|
2183
2204
|
`netRead` / `netWrite` panic on a range outside the buffer.
|
|
2184
2205
|
`tcpListenFlags(host, port, backlog, flags)` is `tcpListen` with flag 1
|
|
2185
2206
|
`SO_REUSEPORT`, so several listeners, in one process or many, share a port (Linux
|
|
@@ -2198,7 +2219,13 @@ loop, `pollAdd(loop, fd, events, token)` / `pollModify(...)` watch `fd` for
|
|
|
2198
2219
|
for `-1`), fills `ready: i32[]` with pairs — `ready[2k]` a token,
|
|
2199
2220
|
`ready[2k + 1]` its events, 4 added for a hang-up or error — and answers how
|
|
2200
2221
|
many, **0 on a timeout or a signal**. It is level-triggered, so what you leave
|
|
2201
|
-
unread is reported again. Add `signalFd()` to the loop to wake on SIGTERM.
|
|
2222
|
+
unread is reported again. Add `signalFd()` to the loop to wake on SIGTERM.
|
|
2223
|
+
`netSetOption(fd, option, value)` sets one socket option from a whitelist:
|
|
2224
|
+
`NET_TCP_NODELAY`, `NET_TCP_QUICKACK` (Linux; `-95` on Darwin),
|
|
2225
|
+
`NET_SO_KEEPALIVE`, `NET_SO_SNDBUF` and `NET_SO_RCVBUF`, `i32` ids exported
|
|
2226
|
+
beside it; any other id is `-22`. Linux drops quick-ACK mode on its own, so set
|
|
2227
|
+
it again after each response. The ids are not module constants: pass them
|
|
2228
|
+
directly. None
|
|
2202
2229
|
exists on a wasm target, and under Node each throws.
|
|
2203
2230
|
|
|
2204
2231
|
**Arena.** `Arena.mark()`, `Arena.used()` and `using a = arena()` — see below.
|
|
@@ -2605,6 +2632,20 @@ the array open: end it and send the rest in the next statement. Every other
|
|
|
2605
2632
|
guide's [PostgreSQL page](guide/using-nish/postgres.md#array-parameters) its
|
|
2606
2633
|
walk-through.)
|
|
2607
2634
|
|
|
2635
|
+
**Read PostgreSQL ids, counts and times without parsing them** — there is no
|
|
2636
|
+
driver option for binary results: in `nish/net/postgres`, open the bind with
|
|
2637
|
+
`bindStartBinary(name)` instead of `bindStart(name)`, and every result column
|
|
2638
|
+
of that execution comes in binary. Read an `int2`/`int4`/`int8` with
|
|
2639
|
+
`binaryInt(c)`, a `bool` with `binaryBool(c)`, a `float8` with
|
|
2640
|
+
`binaryFloat(c)`, a `timestamptz` with `conn.binary.timestamp(conn.inputBuffer(),
|
|
2641
|
+
conn.colStart(c), conn.colLength(c), out, at)` (or its microseconds since 2000
|
|
2642
|
+
with `binaryInt(c)`, written out by `conn.binary.iso(micros, out, at)`), and a
|
|
2643
|
+
`text` column with `columnText(c)` as before. Cast anything else (`numeric`,
|
|
2644
|
+
`text[]`) to `text` in the SQL. (No block, as for `nish/text`;
|
|
2645
|
+
`tests/postgres/live`'s `binary` scenario runs it against a server, and the
|
|
2646
|
+
user guide's [PostgreSQL page](guide/using-nish/postgres.md#binary-results)
|
|
2647
|
+
its walk-through.)
|
|
2648
|
+
|
|
2608
2649
|
**Batch a server's keyed reads into one PostgreSQL query** — there is no
|
|
2609
2650
|
DataLoader and no `setTimeout` to collect a tick's keys: in `nish/net/postgres`,
|
|
2610
2651
|
a `PgBatcher` built from a `PgBatchConfig` (`name`, `select` reading the key as
|
package/package.json
CHANGED
package/runtime/browser.mjs
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* - `exit(code)` throws a `NishExit` carrying the code, since a page cannot
|
|
11
11
|
* end itself; the caller that started the program catches it, and does
|
|
12
12
|
* not call the module again (docs/security/runtime-browser.md, BROWSER-2).
|
|
13
|
-
* - `monotonicNanos` reads `performance.now()`, `
|
|
14
|
-
* `
|
|
15
|
-
* is the program alone.
|
|
13
|
+
* - `monotonicNanos` reads `performance.now()`, `wallClockNanos` `Date.now()`,
|
|
14
|
+
* `getenv` answers `null`, `isTerminal` answers `false` and `terminalSize`
|
|
15
|
+
* `[-25, 0]`, and `argv()` is the program alone.
|
|
16
16
|
* - Every file-system, process and machine call panics, naming itself and
|
|
17
17
|
* the browser.
|
|
18
18
|
*/
|
|
@@ -69,6 +69,7 @@ installHost({
|
|
|
69
69
|
call(name) {
|
|
70
70
|
if (name === "getenv") return null;
|
|
71
71
|
if (name === "monotonicNanos") return BigInt(Math.round(performance.now() * 1e6));
|
|
72
|
+
if (name === "wallClockNanos") return BigInt(Date.now()) * 1000000n;
|
|
72
73
|
// A page has no terminal, which `nish:term` answers as a pipe does.
|
|
73
74
|
if (name === "isTerminal") return false;
|
|
74
75
|
if (name === "terminalSize") return [-25, 0];
|
package/runtime/core/host.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare function log(x: unknown): void;
|
|
|
35
35
|
export declare function error(x: unknown): void;
|
|
36
36
|
export declare function write(s: string): void;
|
|
37
37
|
export declare function writeError(s: string): void;
|
|
38
|
+
export declare function writeBytes(bytes: readonly u8[], off: i32, len: i32): i32;
|
|
38
39
|
export declare function panic(message: string): never;
|
|
39
40
|
export declare function exit(code: i32): never;
|
|
40
41
|
export declare function argv(): string[];
|
|
@@ -43,6 +44,12 @@ export declare function readFileSyncOrNull(path: string): string | null;
|
|
|
43
44
|
export declare function readFileBytesSync(path: string): u8[] | null;
|
|
44
45
|
export declare function writeFileSync(path: string, data: string): void;
|
|
45
46
|
export declare function appendFileSync(path: string, data: string): void;
|
|
47
|
+
export declare function writeFileBytesSync(path: string, bytes: readonly u8[]): i32;
|
|
48
|
+
export declare function renameSync(from: string, to: string): i32;
|
|
49
|
+
export declare function unlinkSync(path: string): i32;
|
|
50
|
+
export declare function writeFileSyncMode(path: string, data: string, mode: i32): i32;
|
|
51
|
+
export declare function createFileExclusiveSync(path: string, data: string, mode: i32): i32;
|
|
52
|
+
export declare function mkdirSyncMode(path: string, mode: i32): i32;
|
|
46
53
|
export declare function mkdirSync(path: string): boolean;
|
|
47
54
|
export declare function isDirectorySync(path: string): boolean;
|
|
48
55
|
export declare function readdirSync(path: string): string[] | null;
|
|
@@ -52,10 +59,12 @@ export declare function arch(): string;
|
|
|
52
59
|
export declare function getenv(name: string): string | null;
|
|
53
60
|
export declare function spawnSync(argv: string[]): number;
|
|
54
61
|
export declare function spawnSyncTo(argv: string[], stdoutPath: string, stderrPath: string): number;
|
|
62
|
+
export declare function spawnPiped(argv: string[], stdin: readonly u8[], stdout: u8[], stderr: u8[]): i32;
|
|
55
63
|
export declare function kill(pid: i32, sig: i32): i32;
|
|
56
64
|
export declare function availableParallelism(): i32;
|
|
57
65
|
export declare function totalMemory(): i64;
|
|
58
66
|
export declare function monotonicNanos(): i64;
|
|
67
|
+
export declare function wallClockNanos(): i64;
|
|
59
68
|
export declare function statMtimeSync(path: string): f64;
|
|
60
69
|
export declare function lstatOwnerModeSync(path: string): i64;
|
|
61
70
|
export declare function geteuid(): i64;
|
|
@@ -69,6 +78,9 @@ export declare function spawn(argv: string[]): i32;
|
|
|
69
78
|
export declare function waitPid(pid: i32, flags: i32): i32[];
|
|
70
79
|
export declare function signalFd(): i32;
|
|
71
80
|
export declare function readSignal(fd: i32): i32;
|
|
81
|
+
/** These two have no reading under Node: each throws, naming itself. */
|
|
82
|
+
export declare function setNice(n: i32): i32;
|
|
83
|
+
export declare function setIdlePriority(): i32;
|
|
72
84
|
/** What each `nish:net` function is under the core: a throw naming `name`. */
|
|
73
85
|
export declare function noNetReading(name: string): never;
|
|
74
86
|
/** What `readStdin`, `waitStdin`, `setRawMode` and `setTerminalRestore` are under the core: a throw naming `name`. */
|
package/runtime/core/host.mjs
CHANGED
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
* its own fails loudly rather than writing nowhere.
|
|
16
16
|
*
|
|
17
17
|
* The functions that have no synchronous reading under Node (`spawn`,
|
|
18
|
-
* `waitPid`, `signalFd`, `readSignal`, the `nish:net` set)
|
|
19
|
-
* asking any
|
|
18
|
+
* `waitPid`, `signalFd`, `readSignal`, the `nish:net` set), and `setNice` and
|
|
19
|
+
* `setIdlePriority`, which have none at all, throw here without asking any
|
|
20
|
+
* host.
|
|
20
21
|
*/
|
|
22
|
+
import { panicSlice, toIndex } from "./checks.mjs";
|
|
21
23
|
|
|
22
24
|
/** What every member of the default host throws: no adapter has been imported. */
|
|
23
25
|
export class NishNoHost extends Error {
|
|
@@ -86,6 +88,18 @@ export function writeError(s) {
|
|
|
86
88
|
host.writeErr(s);
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
/**
|
|
92
|
+
* `writeBytes(bytes, off, len)`: the range checked as the compiled call checks
|
|
93
|
+
* it, `0 <= off <= off + len <= bytes.length`, through the slice panic, then
|
|
94
|
+
* the host's write of those bytes to stdout.
|
|
95
|
+
*/
|
|
96
|
+
export function writeBytes(bytes, off, len) {
|
|
97
|
+
const from = toIndex(off);
|
|
98
|
+
const to = from + toIndex(len);
|
|
99
|
+
if (!(from >= 0 && from <= to && to <= bytes.length)) panicSlice(from, to, bytes.length);
|
|
100
|
+
return host.call("writeBytes", [bytes, from, to]);
|
|
101
|
+
}
|
|
102
|
+
|
|
89
103
|
/** `panic(message)`: the message on stderr, then exit 1. */
|
|
90
104
|
export function panic(message) {
|
|
91
105
|
host.writeErr(`${message}\n`);
|
|
@@ -131,6 +145,30 @@ export function appendFileSync(path, data) {
|
|
|
131
145
|
return host.call("appendFileSync", [path, data]);
|
|
132
146
|
}
|
|
133
147
|
|
|
148
|
+
export function writeFileBytesSync(path, bytes) {
|
|
149
|
+
return host.call("writeFileBytesSync", [path, bytes]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function renameSync(from, to) {
|
|
153
|
+
return host.call("renameSync", [from, to]);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function unlinkSync(path) {
|
|
157
|
+
return host.call("unlinkSync", [path]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function writeFileSyncMode(path, data, mode) {
|
|
161
|
+
return host.call("writeFileSyncMode", [path, data, mode]);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function createFileExclusiveSync(path, data, mode) {
|
|
165
|
+
return host.call("createFileExclusiveSync", [path, data, mode]);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function mkdirSyncMode(path, mode) {
|
|
169
|
+
return host.call("mkdirSyncMode", [path, mode]);
|
|
170
|
+
}
|
|
171
|
+
|
|
134
172
|
export function mkdirSync(path) {
|
|
135
173
|
return host.call("mkdirSync", [path]);
|
|
136
174
|
}
|
|
@@ -167,6 +205,18 @@ export function spawnSyncTo(argv, out, err) {
|
|
|
167
205
|
return host.call("spawnSyncTo", [argv, out, err]);
|
|
168
206
|
}
|
|
169
207
|
|
|
208
|
+
/**
|
|
209
|
+
* `spawnPiped(argv, stdin, stdout, stderr)`: the host runs the child and hands
|
|
210
|
+
* back its status and both streams' bytes, and they are appended here, as the
|
|
211
|
+
* runtime appends them to the caller's arrays.
|
|
212
|
+
*/
|
|
213
|
+
export function spawnPiped(argv, input, out, err) {
|
|
214
|
+
const [status, outBytes, errBytes] = host.call("spawnPiped", [argv, input]);
|
|
215
|
+
for (const b of outBytes) out.push(b);
|
|
216
|
+
for (const b of errBytes) err.push(b);
|
|
217
|
+
return status;
|
|
218
|
+
}
|
|
219
|
+
|
|
170
220
|
export function kill(pid, sig) {
|
|
171
221
|
return host.call("kill", [pid, sig]);
|
|
172
222
|
}
|
|
@@ -183,6 +233,10 @@ export function monotonicNanos() {
|
|
|
183
233
|
return host.call("monotonicNanos", []);
|
|
184
234
|
}
|
|
185
235
|
|
|
236
|
+
export function wallClockNanos() {
|
|
237
|
+
return host.call("wallClockNanos", []);
|
|
238
|
+
}
|
|
239
|
+
|
|
186
240
|
export function statMtimeSync(path) {
|
|
187
241
|
return host.call("statMtimeSync", [path]);
|
|
188
242
|
}
|
|
@@ -259,6 +313,24 @@ export function waitPid() {
|
|
|
259
313
|
return noProcessReading("waitPid");
|
|
260
314
|
}
|
|
261
315
|
|
|
316
|
+
/**
|
|
317
|
+
* `setNice(n)` and `setIdlePriority()` have no reading under Node: Node has one
|
|
318
|
+
* of the nice value (`os.setPriority`) but none of `SCHED_IDLE`, and a reading
|
|
319
|
+
* of one without the other would differ from the native build on the same host.
|
|
320
|
+
* Each throws, naming itself, as `runtime/nish.mjs` does.
|
|
321
|
+
*/
|
|
322
|
+
function noSchedulingReading(name) {
|
|
323
|
+
throw new Error(`\`${name}\` has no reading under Node: it changes how the kernel schedules the native program`);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export function setNice() {
|
|
327
|
+
return noSchedulingReading("setNice");
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export function setIdlePriority() {
|
|
331
|
+
return noSchedulingReading("setIdlePriority");
|
|
332
|
+
}
|
|
333
|
+
|
|
262
334
|
/**
|
|
263
335
|
* `signalFd()` and `readSignal(fd)` have no faithful reading under Node, and
|
|
264
336
|
* these say so rather than answer something else. Node delivers a signal to
|
package/runtime/nish.d.ts
CHANGED
|
@@ -227,6 +227,12 @@ declare function readCString(p: CPtr): string;
|
|
|
227
227
|
declare function write(s: string): void;
|
|
228
228
|
/** `s` to stderr, likewise. */
|
|
229
229
|
declare function writeError(s: string): void;
|
|
230
|
+
/**
|
|
231
|
+
* `bytes[off .. off + len)` to stdout, every byte as it is, partial writes and
|
|
232
|
+
* interruptions retried: the count, or a negative errno. A range outside
|
|
233
|
+
* `bytes` panics, as `dst.set` does. The shape is `netWrite`'s.
|
|
234
|
+
*/
|
|
235
|
+
declare function writeBytes(bytes: readonly u8[], off: i32, len: i32): i32;
|
|
230
236
|
/**
|
|
231
237
|
* `message` and a newline to stderr, then exit 1. Terminates control flow, so
|
|
232
238
|
* it is `never`: that is what lets `tsc` agree that a function ending in a
|
|
@@ -257,6 +263,46 @@ declare function readFileBytesSync(path: string): u8[] | null;
|
|
|
257
263
|
declare function writeFileSync(path: string, data: string): void;
|
|
258
264
|
/** `data` added at the end of the file, with the same refusal of a symbolic link. */
|
|
259
265
|
declare function appendFileSync(path: string, data: string): void;
|
|
266
|
+
/**
|
|
267
|
+
* The file's contents replaced by `bytes`, created at 0644 when missing, with
|
|
268
|
+
* the same refusal of a symbolic link: the byte count, or a negative errno.
|
|
269
|
+
* Never an exit.
|
|
270
|
+
*/
|
|
271
|
+
declare function writeFileBytesSync(path: string, bytes: readonly u8[]): i32;
|
|
272
|
+
/**
|
|
273
|
+
* `from` moved to `to`, replacing a file there in one step on one file system:
|
|
274
|
+
* 0, or a negative errno (-18 across file systems, -2 for a missing `from`).
|
|
275
|
+
*/
|
|
276
|
+
declare function renameSync(from: string, to: string): i32;
|
|
277
|
+
/** The name `path` removed: 0, or a negative errno. A directory is refused, not removed. */
|
|
278
|
+
declare function unlinkSync(path: string): i32;
|
|
279
|
+
/**
|
|
280
|
+
* `writeFileSync` with an explicit `mode`: the file is exactly `mode`
|
|
281
|
+
* (`0o600` for a secret) before a byte of `data` is in it, whatever the umask
|
|
282
|
+
* or a file already there had, and a symbolic link at the path is refused
|
|
283
|
+
* (-40). The byte count, or a negative errno: -22 for a mode outside
|
|
284
|
+
* 0..0o777, the setuid, setgid and sticky bits included. The file is
|
|
285
|
+
* truncated and written in place, so a crash or a failed write leaves it
|
|
286
|
+
* empty or partial, and a file this process may write but does not own is
|
|
287
|
+
* emptied before the mode change answers -1 (`EPERM`). For a file that must
|
|
288
|
+
* be the old one or the new one, write a temporary name with this and move it
|
|
289
|
+
* with `renameSync`. Never an exit.
|
|
290
|
+
*/
|
|
291
|
+
declare function writeFileSyncMode(path: string, data: string, mode: i32): i32;
|
|
292
|
+
/**
|
|
293
|
+
* `data` in a new file of exactly `mode`, created only if nothing is at `path`:
|
|
294
|
+
* -17 when something is, a dangling symbolic link included. Of several
|
|
295
|
+
* processes racing for one path exactly one succeeds, so it takes a lock. The
|
|
296
|
+
* byte count, or a negative errno; a write that fails after the create
|
|
297
|
+
* removes the file, so the lock is not left taken. Never an exit.
|
|
298
|
+
*/
|
|
299
|
+
declare function createFileExclusiveSync(path: string, data: string, mode: i32): i32;
|
|
300
|
+
/**
|
|
301
|
+
* One directory made with `mode` less the umask (`0o700` is exact under any
|
|
302
|
+
* umask that leaves the owner's bits): 0, or a negative errno. A path already
|
|
303
|
+
* there is -17 and its mode is not changed; -22 for a mode outside 0..0o777.
|
|
304
|
+
*/
|
|
305
|
+
declare function mkdirSyncMode(path: string, mode: i32): i32;
|
|
260
306
|
/** One directory, not recursive; whether a directory is there afterwards. */
|
|
261
307
|
declare function mkdirSync(path: string): boolean;
|
|
262
308
|
/** Whether a directory is at `path` right now. One `stat`, and never an exit. */
|
|
@@ -280,6 +326,13 @@ declare function spawnSync(argv: string[]): number;
|
|
|
280
326
|
* either path is refused, as `writeFileSync` refuses one, and the answer is -1.
|
|
281
327
|
*/
|
|
282
328
|
declare function spawnSyncTo(argv: string[], stdoutPath: string, stderrPath: string): number;
|
|
329
|
+
/**
|
|
330
|
+
* The same run with all three streams on pipes: `stdin` is written to the
|
|
331
|
+
* child and closed, and what it prints is appended to `stdout` and `stderr`.
|
|
332
|
+
* The status as `spawnSync` answers it, or -2 when a stream passed 16 MiB:
|
|
333
|
+
* the child is then killed and each array keeps at most the first 16 MiB.
|
|
334
|
+
*/
|
|
335
|
+
declare function spawnPiped(argv: string[], stdin: readonly u8[], stdout: u8[], stderr: u8[]): i32;
|
|
283
336
|
/**
|
|
284
337
|
* Start `argv[0]` through `PATH` without waiting: the child's pid, or a
|
|
285
338
|
* negative errno. The child is the program's until `waitPid` reaps it. No
|
|
@@ -302,6 +355,21 @@ declare function waitPid(pid: i32, flags: i32): i32[];
|
|
|
302
355
|
declare function availableParallelism(): i32;
|
|
303
356
|
/** Bytes of physical memory, or -1 when the host does not say. */
|
|
304
357
|
declare function totalMemory(): i64;
|
|
358
|
+
/**
|
|
359
|
+
* Set this process's nice value to `n`: 0, or a negative errno. The kernel
|
|
360
|
+
* clamps `n` to -20..19, and lowering it below the current value needs the
|
|
361
|
+
* privilege to (-13 without it on Linux). Children started afterwards inherit
|
|
362
|
+
* it. Throws under Node.
|
|
363
|
+
*/
|
|
364
|
+
declare function setNice(n: i32): i32;
|
|
365
|
+
/**
|
|
366
|
+
* Move this process to `SCHED_IDLE`, which runs it only when nothing else wants
|
|
367
|
+
* the CPU: 0, or a negative errno, and -95 where the host has no such policy
|
|
368
|
+
* (Darwin). An unprivileged process can never leave `SCHED_IDLE` again, and an
|
|
369
|
+
* idle process can starve on a saturated machine, so a caller keeps a
|
|
370
|
+
* normal-priority fallback for work that must finish. Throws under Node.
|
|
371
|
+
*/
|
|
372
|
+
declare function setIdlePriority(): i32;
|
|
305
373
|
/** One environment variable, or `null` when it is unset (an empty value is a set variable). */
|
|
306
374
|
declare function getenv(name: string): string | null;
|
|
307
375
|
/**
|
|
@@ -309,6 +377,11 @@ declare function getenv(name: string): string | null;
|
|
|
309
377
|
* origin is arbitrary, so only the difference between two reads is meaningful.
|
|
310
378
|
*/
|
|
311
379
|
declare function monotonicNanos(): i64;
|
|
380
|
+
/**
|
|
381
|
+
* The wall clock in nanoseconds since the Unix epoch, for dating an event. It
|
|
382
|
+
* steps when the system time is set, so a duration is `monotonicNanos`'s.
|
|
383
|
+
*/
|
|
384
|
+
declare function wallClockNanos(): i64;
|
|
312
385
|
/**
|
|
313
386
|
* The modification time of `path` in milliseconds since the epoch, with the
|
|
314
387
|
* sub-millisecond fraction the file system keeps (Node's `mtimeMs`), or NaN
|
|
@@ -381,6 +454,26 @@ declare function pollModify(loop: i32, fd: i32, events: i32, token: i32): i32;
|
|
|
381
454
|
declare function pollRemove(loop: i32, fd: i32): i32;
|
|
382
455
|
/** Wait up to `timeoutMs` (negative: forever); pairs `ready[2k]` token, `ready[2k + 1]` events (4: hang-up or error). */
|
|
383
456
|
declare function pollWait(loop: i32, ready: i32[], timeoutMs: i32): i32;
|
|
457
|
+
/**
|
|
458
|
+
* Set one socket option from a whitelist: `option` is one of the `NET_*` ids
|
|
459
|
+
* below, and any other is -22; there is no raw level and option number. 0, or
|
|
460
|
+
* a negative errno (-9 a closed descriptor, -88 not a socket).
|
|
461
|
+
*/
|
|
462
|
+
declare function netSetOption(fd: i32, option: i32, value: i32): i32;
|
|
463
|
+
/** `TCP_NODELAY`: `value` 1 sends a small write at once, 0 lets Nagle batch it. */
|
|
464
|
+
declare const NET_TCP_NODELAY: i32;
|
|
465
|
+
/**
|
|
466
|
+
* `TCP_QUICKACK` (Linux; -95 elsewhere): `value` 1 acknowledges at once, 0
|
|
467
|
+
* delays. Linux does not keep quick-ACK mode: the kernel leaves it on its own,
|
|
468
|
+
* so a server that wants a mode sets it again after every response.
|
|
469
|
+
*/
|
|
470
|
+
declare const NET_TCP_QUICKACK: i32;
|
|
471
|
+
/** `SO_KEEPALIVE`: `value` 1 probes an idle connection, 0 does not. */
|
|
472
|
+
declare const NET_SO_KEEPALIVE: i32;
|
|
473
|
+
/** `SO_SNDBUF`: the send buffer, `value` in bytes; Linux doubles the value it stores. */
|
|
474
|
+
declare const NET_SO_SNDBUF: i32;
|
|
475
|
+
/** `SO_RCVBUF`: the receive buffer, `value` in bytes; Linux doubles the value it stores. */
|
|
476
|
+
declare const NET_SO_RCVBUF: i32;
|
|
384
477
|
|
|
385
478
|
// ---- `nish:term` ------------------------------------------------------------------
|
|
386
479
|
//
|
|
@@ -433,6 +526,9 @@ declare var crypto: {
|
|
|
433
526
|
//
|
|
434
527
|
// `docs/LANGUAGE.md` -> Builtins -> Builtin modules is the normative list.
|
|
435
528
|
|
|
529
|
+
// Every negative errno a file call answers is the platform's own, untranslated:
|
|
530
|
+
// the numbers shown here are Linux's (-2 ENOENT, -17 EEXIST, -18 EXDEV, -22
|
|
531
|
+
// EINVAL, -40 ELOOP), and Darwin's differ (ELOOP is -62 there).
|
|
436
532
|
declare module "nish:fs" {
|
|
437
533
|
export function readFileSync(path: string): string;
|
|
438
534
|
export function readFileSyncOrNull(path: string): string | null;
|
|
@@ -441,6 +537,18 @@ declare module "nish:fs" {
|
|
|
441
537
|
export function writeFileSync(path: string, data: string): void;
|
|
442
538
|
/** Refuses a symbolic link as the last component of the path, as the global does. */
|
|
443
539
|
export function appendFileSync(path: string, data: string): void;
|
|
540
|
+
/** The byte count, or a negative errno; refuses a symbolic link as `writeFileSync` does. */
|
|
541
|
+
export function writeFileBytesSync(path: string, bytes: readonly u8[]): i32;
|
|
542
|
+
/** 0, or a negative errno: -18 across file systems. */
|
|
543
|
+
export function renameSync(from: string, to: string): i32;
|
|
544
|
+
/** 0, or a negative errno: a directory is refused, not removed. */
|
|
545
|
+
export function unlinkSync(path: string): i32;
|
|
546
|
+
/** The byte count, or a negative errno; the file is exactly `mode` (0..0o777) before it holds a byte, a link refused, written in place. */
|
|
547
|
+
export function writeFileSyncMode(path: string, data: string, mode: i32): i32;
|
|
548
|
+
/** As `writeFileSyncMode`, but -17 when anything is at `path`: one racer wins; a failed write removes the file. */
|
|
549
|
+
export function createFileExclusiveSync(path: string, data: string, mode: i32): i32;
|
|
550
|
+
/** 0, or a negative errno: -17 for a path already there, whose mode is left alone. */
|
|
551
|
+
export function mkdirSyncMode(path: string, mode: i32): i32;
|
|
444
552
|
/** `true` when the directory was created, `false` when it already existed. */
|
|
445
553
|
export function mkdirSync(path: string): boolean;
|
|
446
554
|
export function isDirectorySync(path: string): boolean;
|
|
@@ -465,6 +573,11 @@ declare module "nish:process" {
|
|
|
465
573
|
* at either path is refused, and the answer is -1.
|
|
466
574
|
*/
|
|
467
575
|
export function spawnSyncTo(argv: string[], stdoutPath: string, stderrPath: string): number;
|
|
576
|
+
/**
|
|
577
|
+
* The same run with `stdin` written to the child and its stdout and stderr
|
|
578
|
+
* appended to the two arrays: the status, or -2 past 16 MiB on a stream.
|
|
579
|
+
*/
|
|
580
|
+
export function spawnPiped(argv: string[], stdin: readonly u8[], stdout: u8[], stderr: u8[]): i32;
|
|
468
581
|
/** Start a child without waiting: its pid, or a negative errno. */
|
|
469
582
|
export function spawn(argv: string[]): i32;
|
|
470
583
|
/** Send 0, 2, 9 or 15 to `pid`: 0, or a negative errno; any other signal is -22. */
|
|
@@ -475,11 +588,21 @@ declare module "nish:process" {
|
|
|
475
588
|
export function availableParallelism(): i32;
|
|
476
589
|
/** Bytes of physical memory, or -1. */
|
|
477
590
|
export function totalMemory(): i64;
|
|
591
|
+
/** Set this process's nice value (clamped to -20..19): 0, or a negative errno. */
|
|
592
|
+
export function setNice(n: i32): i32;
|
|
593
|
+
/**
|
|
594
|
+
* Move this process to `SCHED_IDLE`: 0, a negative errno, or -95 off Linux.
|
|
595
|
+
* An unprivileged process can never leave it, and an idle process can starve
|
|
596
|
+
* on a saturated machine, so a caller keeps a normal-priority fallback.
|
|
597
|
+
*/
|
|
598
|
+
export function setIdlePriority(): i32;
|
|
478
599
|
/**
|
|
479
600
|
* A monotonic clock in nanoseconds. The origin is arbitrary, so only the
|
|
480
601
|
* difference between two reads is meaningful.
|
|
481
602
|
*/
|
|
482
603
|
export function monotonicNanos(): i64;
|
|
604
|
+
/** The wall clock in nanoseconds since the Unix epoch; it steps when the system time is set. */
|
|
605
|
+
export function wallClockNanos(): i64;
|
|
483
606
|
/** A descriptor readable when SIGTERM or SIGINT arrives; the same one every call, or -1. */
|
|
484
607
|
export function signalFd(): i32;
|
|
485
608
|
/** Block until SIGTERM or SIGINT arrives: 15 or 2, or -1 for a descriptor that is not `signalFd()`'s. */
|
|
@@ -538,6 +661,26 @@ declare module "nish:net" {
|
|
|
538
661
|
export function pollRemove(loop: i32, fd: i32): i32;
|
|
539
662
|
/** Wait up to `timeoutMs` (negative: forever); pairs `ready[2k]` token, `ready[2k + 1]` events (4: hang-up or error). */
|
|
540
663
|
export function pollWait(loop: i32, ready: i32[], timeoutMs: i32): i32;
|
|
664
|
+
/**
|
|
665
|
+
* Set one socket option from a whitelist: `option` is one of the `NET_*` ids
|
|
666
|
+
* below, and any other is -22; there is no raw level and option number. 0, or
|
|
667
|
+
* a negative errno (-9 a closed descriptor, -88 not a socket).
|
|
668
|
+
*/
|
|
669
|
+
export function netSetOption(fd: i32, option: i32, value: i32): i32;
|
|
670
|
+
/** `TCP_NODELAY`: `value` 1 sends a small write at once, 0 lets Nagle batch it. */
|
|
671
|
+
export const NET_TCP_NODELAY: i32;
|
|
672
|
+
/**
|
|
673
|
+
* `TCP_QUICKACK` (Linux; -95 elsewhere): `value` 1 acknowledges at once, 0
|
|
674
|
+
* delays. Linux does not keep quick-ACK mode: the kernel leaves it on its own,
|
|
675
|
+
* so a server that wants a mode sets it again after every response.
|
|
676
|
+
*/
|
|
677
|
+
export const NET_TCP_QUICKACK: i32;
|
|
678
|
+
/** `SO_KEEPALIVE`: `value` 1 probes an idle connection, 0 does not. */
|
|
679
|
+
export const NET_SO_KEEPALIVE: i32;
|
|
680
|
+
/** `SO_SNDBUF`: the send buffer, `value` in bytes; Linux doubles the value it stores. */
|
|
681
|
+
export const NET_SO_SNDBUF: i32;
|
|
682
|
+
/** `SO_RCVBUF`: the receive buffer, `value` in bytes; Linux doubles the value it stores. */
|
|
683
|
+
export const NET_SO_RCVBUF: i32;
|
|
541
684
|
}
|
|
542
685
|
|
|
543
686
|
declare module "nish:unsafe" {
|
|
@@ -560,6 +703,11 @@ declare module "nish:io" {
|
|
|
560
703
|
export function write(s: string): void;
|
|
561
704
|
/** The same, on stderr. */
|
|
562
705
|
export function writeError(s: string): void;
|
|
706
|
+
/**
|
|
707
|
+
* `bytes[off .. off + len)` to stdout, every byte as it is: the count, or a
|
|
708
|
+
* negative errno. A range outside `bytes` panics, as `dst.set` does.
|
|
709
|
+
*/
|
|
710
|
+
export function writeBytes(bytes: readonly u8[], off: i32, len: i32): i32;
|
|
563
711
|
/** `message` to stderr, then exit 1. A terminator, as `process.exit` is. */
|
|
564
712
|
export function panic(message: string): never;
|
|
565
713
|
}
|
package/runtime/nish.h
CHANGED
|
@@ -396,6 +396,36 @@ nish_array *nish_readdir(const nish_str *path);
|
|
|
396
396
|
* and the bytes live in the arena, so copy what you keep before the next reset
|
|
397
397
|
* or release. */
|
|
398
398
|
nish_array *nish_read_file_bytes(const nish_str *path);
|
|
399
|
+
/* `renameSync(from, to)`, `unlinkSync(path)` and `writeFileBytesSync(path,
|
|
400
|
+
* bytes)`: rename(2), unlink(2), and every element of a `u8[]` written to a
|
|
401
|
+
* file opened as `nish_write_file` opens it (`O_TRUNC`, 0644, a link refused).
|
|
402
|
+
* None exits: each answers 0 (the write, the length written) or a negative
|
|
403
|
+
* errno — -EXDEV for a rename across file systems, which moves nothing, and
|
|
404
|
+
* -EISDIR or -EPERM for a directory handed to `nish_unlink`, which never calls
|
|
405
|
+
* rmdir. A path holding a NUL answers -EINVAL, not -ENOENT, so a program can
|
|
406
|
+
* tell a malformed path from a missing file. The numbers are the platform's
|
|
407
|
+
* errno values, untranslated: -ELOOP is -40 on Linux and -62 on Darwin. */
|
|
408
|
+
int32_t nish_rename(const nish_str *from, const nish_str *to);
|
|
409
|
+
int32_t nish_unlink(const nish_str *path);
|
|
410
|
+
int32_t nish_write_file_bytes(const nish_str *path, const nish_array *bytes);
|
|
411
|
+
/* `writeFileSyncMode(path, data, mode)`, `createFileExclusiveSync(path, data,
|
|
412
|
+
* mode)` and `mkdirSyncMode(path, mode)`: a file written, or created only if
|
|
413
|
+
* nothing is at the path (`O_EXCL`), then `fchmod`ed to exactly `mode` before a
|
|
414
|
+
* byte is written; a directory made with `mode & ~umask`. A link at a file's
|
|
415
|
+
* path is refused. The file writers answer the byte count and `nish_mkdir_mode`
|
|
416
|
+
* 0, or a negative platform errno: -EEXIST for an exclusive create or a mkdir
|
|
417
|
+
* that finds the path taken (a directory's mode is then left alone), -EINVAL
|
|
418
|
+
* for a mode outside 0..0777 (the setuid, setgid and sticky bits included) or
|
|
419
|
+
* a path holding a NUL, -ENOSYS under WASI. A failed exclusive create leaves
|
|
420
|
+
* no file behind. */
|
|
421
|
+
int32_t nish_write_file_mode(const nish_str *path, const nish_str *data, int32_t mode);
|
|
422
|
+
int32_t nish_create_file_exclusive(const nish_str *path, const nish_str *data, int32_t mode);
|
|
423
|
+
int32_t nish_mkdir_mode(const nish_str *path, int32_t mode);
|
|
424
|
+
/* `writeBytes(bytes, off, len)` (nish:io), in runtime-os.c: the bytes
|
|
425
|
+
* `[off, off + len)` of a `u8[]` on stdout, a short write finished and `EINTR`
|
|
426
|
+
* retried. The caller has range-checked `off` and `len`. Answers `len`, or the
|
|
427
|
+
* negative errno of the write that failed; never exits. */
|
|
428
|
+
int32_t nish_write_bytes(const nish_array *bytes, int64_t off, int64_t len);
|
|
399
429
|
/* `spawnSync(argv)`: run element 0 of `argv` (searched on `PATH`) with `argv`
|
|
400
430
|
* as its argument vector, wait for it, and answer its exit status, or
|
|
401
431
|
* `128 + n` when signal `n` killed it. -1 when `argv` is empty, when the
|
|
@@ -422,6 +452,17 @@ int32_t nish_spawn_to(const nish_array *argv, const nish_str *out, const nish_st
|
|
|
422
452
|
* own error otherwise, and -ENOSYS under WASI. The child is reaped by
|
|
423
453
|
* `nish_wait_pid`. */
|
|
424
454
|
int32_t nish_spawn_child(const nish_array *argv);
|
|
455
|
+
/* `spawnPiped(argv, stdin, stdout, stderr)`: start element 0 of `argv` as
|
|
456
|
+
* `nish_spawn` does, with the bytes of `stdin` (a `u8[]`) on its standard input
|
|
457
|
+
* and its standard output and error appended to `stdout` and `stderr`, wait for
|
|
458
|
+
* it, and answer `nish_spawn`'s status. -1 is `nish_spawn`'s -1, a pipe or
|
|
459
|
+
* `poll` that fails included, and always under WASI. -2 is a stream that passed
|
|
460
|
+
* 16 MiB: the child is killed with SIGKILL and reaped, and that array holds the
|
|
461
|
+
* stream's first 16 MiB. The two output arrays grow as `push` grows them, so
|
|
462
|
+
* the compiler treats both as pushed. `stdin` is read in place and never
|
|
463
|
+
* copied; SIGPIPE is blocked on the calling thread for the call, a SIGPIPE the
|
|
464
|
+
* call raised is consumed, and the thread's mask is restored after it. */
|
|
465
|
+
int32_t nish_spawn_piped(const nish_array *argv, const nish_array *in, nish_array *out, nish_array *err);
|
|
425
466
|
/* `kill(pid, sig)`: send `sig` to `pid` and answer 0, or a negative errno. Only
|
|
426
467
|
* 0, 2 (SIGINT), 9 (SIGKILL) and 15 (SIGTERM) are sent; any other signal, and
|
|
427
468
|
* a pid of 0 or below, is -EINVAL. -ESRCH when no process has the pid, -EPERM
|
|
@@ -438,6 +479,15 @@ nish_array *nish_wait_pid(int32_t pid, int32_t flags);
|
|
|
438
479
|
/* `totalMemory()`: bytes of physical memory (Linux: `_SC_PHYS_PAGES` times the
|
|
439
480
|
* page size; Darwin: `hw.memsize`), or -1 where the host does not say. */
|
|
440
481
|
int64_t nish_total_memory(void);
|
|
482
|
+
/* `setNice(n)`: this process's nice value set to `n` (`setpriority`), 0 or a
|
|
483
|
+
* negative errno. The kernel clamps `n` to -20..19; lowering it below the
|
|
484
|
+
* current value without the privilege is -EACCES (or -EPERM). -ENOSYS under
|
|
485
|
+
* WASI. */
|
|
486
|
+
int32_t nish_set_nice(int32_t n);
|
|
487
|
+
/* `setIdlePriority()`: this process moved to `SCHED_IDLE` (Linux), 0 or a
|
|
488
|
+
* negative errno; -95 (Linux's EOPNOTSUPP) elsewhere, -ENOSYS under WASI. An
|
|
489
|
+
* unprivileged process cannot leave the policy again. */
|
|
490
|
+
int32_t nish_set_idle_priority(void);
|
|
441
491
|
|
|
442
492
|
/* ---- The environment (WP19 R1) ------------------------------------------
|
|
443
493
|
* `getenv(name)`: the value of environment variable `name`, copied into the
|
|
@@ -485,6 +535,10 @@ const nish_str *nish_arch(void);
|
|
|
485
535
|
* purpose: `readnone` would let LLVM fold the two reads around a measured
|
|
486
536
|
* region into one and measure zero. */
|
|
487
537
|
int64_t nish_monotonic_nanos(void);
|
|
538
|
+
/* `wallClockNanos()`: `CLOCK_REALTIME` in nanoseconds since the epoch, the
|
|
539
|
+
* clock `Date.now` reads at a millisecond's grain. It steps when the system
|
|
540
|
+
* time is set, so it dates an event and measures nothing. */
|
|
541
|
+
int64_t nish_wall_clock_nanos(void);
|
|
488
542
|
|
|
489
543
|
/* ---- The host (WP34 N3), runtime/runtime-host.c --------------------------
|
|
490
544
|
* `Date.now()`: the wall clock, `CLOCK_REALTIME`, in whole milliseconds since
|
|
@@ -542,6 +596,10 @@ bool nish_is_executable(const nish_str *path);
|
|
|
542
596
|
* len)` of `buf`, which the compiled call has range-checked; a write to a
|
|
543
597
|
* gone peer is -32, never SIGPIPE. `nish_net_shutdown(fd, how)`: 0 read, 1
|
|
544
598
|
* write, 2 both. `nish_net_close(fd)`.
|
|
599
|
+
* `nish_net_set_option(fd, option, value)`: one socket option from a
|
|
600
|
+
* whitelist, by the runtime's own id (1 `TCP_NODELAY`, 2 `TCP_QUICKACK`, 3
|
|
601
|
+
* `SO_KEEPALIVE`, 4 `SO_SNDBUF`, 5 `SO_RCVBUF`); any other id is -22, and
|
|
602
|
+
* `TCP_QUICKACK` off Linux is -95.
|
|
545
603
|
* `nish_tcp_connect(addr)`: a new socket connecting to `addr`, answered at
|
|
546
604
|
* once; its `EINPROGRESS` is not a failure, and any other closes it.
|
|
547
605
|
* `nish_connect_result(fd)`: `SO_ERROR` once the socket is writable, 0 when
|
|
@@ -576,6 +634,7 @@ int32_t nish_net_read(int32_t fd, nish_array *buf, int64_t off, int64_t len);
|
|
|
576
634
|
int32_t nish_net_write(int32_t fd, const nish_array *buf, int64_t off, int64_t len);
|
|
577
635
|
int32_t nish_net_shutdown(int32_t fd, int32_t how);
|
|
578
636
|
int32_t nish_net_close(int32_t fd);
|
|
637
|
+
int32_t nish_net_set_option(int32_t fd, int32_t option, int32_t value);
|
|
579
638
|
int32_t nish_tcp_connect(const nish_array *addr);
|
|
580
639
|
int32_t nish_connect_result(int32_t fd);
|
|
581
640
|
int32_t nish_udp_bind(const nish_str *host, int32_t port, int32_t flags);
|