feat(runtime): Unix domain socket natives #430

Merged
argus merged 1 commit from loop/428-unix-socket-natives into main 2026-10-23 14:21:01 +00:00
Collaborator

Closes #428

Step 1 of #119: two natives of std/network, networkListenUnix(path, backlog) and networkConnectUnix(path) (torb_network_listen_unix, torb_network_connect_unix in runtime/io.c), with hooks in runtime/os/posix_io.c and runtime/os/iocp.c.

  • torb_io_address stays IP-only; the path crosses as text on the socket record / operation. Empty, NUL byte or longer than sun_path (terminating zero included) is invalid argument, never truncated; no abstract names.
  • Existing accept, receive, send, shutdown and close work on the handles. TCP socket options are invalid argument on a Unix stream.
  • The listener removes the socket file it bound when its handle closes (device/inode checked, best effort); a failed bind removes nothing.
  • torb_sandbox_check_unix(verb, path) in runtime/sandbox.c, called by both natives; listed in the header comment. unrestricted passes.
  • Windows: AcceptEx gets a third slot for AF_UNIX. ConnectEx needs a bound socket and AF_UNIX has no unnamed address to bind to, so the connect runs on the core's helper thread (torb_io_system_unix_connect_blocks). Not run on Windows yet.
  • Manifest: two entries in networkEntries() (Ready); two keep/network rows in docs/design/NATIVES.md (counts 178/533); NETWORK.md section 4 "Unix domain sockets, as built (step 1)" and section 10 names torb_sandbox_check_unix.
  • Tests: runtime/tests/io_test.c (round trip, path in use, nobody listening, invalid paths, replaced file kept, close wakes receive, sandbox refusal; POSIX only) and runtime/tests/sandbox_test.c.

Notes for review:

  • No torb binary and no C compiler were available where this was written, so torb_natives.h and machine_natives.c were regenerated with a script that mimics torb natives --header (sorted by symbol, thunks renumbered, count 307 to 309), and nothing was compiled locally. CI's generated-file check and runtime/build.sh are the first real run; I fix on the same branch if they are red.
  • This is the first commit of the seed rule (new natives, no std/ change here); the seed refresh is not part of this PR.
Closes #428 Step 1 of #119: two natives of `std/network`, `networkListenUnix(path, backlog)` and `networkConnectUnix(path)` (`torb_network_listen_unix`, `torb_network_connect_unix` in `runtime/io.c`), with hooks in `runtime/os/posix_io.c` and `runtime/os/iocp.c`. - `torb_io_address` stays IP-only; the path crosses as text on the socket record / operation. Empty, NUL byte or longer than `sun_path` (terminating zero included) is `invalid argument`, never truncated; no abstract names. - Existing accept, receive, send, shutdown and close work on the handles. TCP socket options are `invalid argument` on a Unix stream. - The listener removes the socket file it bound when its handle closes (device/inode checked, best effort); a failed bind removes nothing. - `torb_sandbox_check_unix(verb, path)` in `runtime/sandbox.c`, called by both natives; listed in the header comment. `unrestricted` passes. - Windows: `AcceptEx` gets a third slot for `AF_UNIX`. `ConnectEx` needs a bound socket and `AF_UNIX` has no unnamed address to bind to, so the connect runs on the core's helper thread (`torb_io_system_unix_connect_blocks`). Not run on Windows yet. - Manifest: two entries in `networkEntries()` (Ready); two `keep`/`network` rows in `docs/design/NATIVES.md` (counts 178/533); `NETWORK.md` section 4 "Unix domain sockets, as built (step 1)" and section 10 names `torb_sandbox_check_unix`. - Tests: `runtime/tests/io_test.c` (round trip, path in use, nobody listening, invalid paths, replaced file kept, close wakes receive, sandbox refusal; POSIX only) and `runtime/tests/sandbox_test.c`. Notes for review: - No `torb` binary and no C compiler were available where this was written, so `torb_natives.h` and `machine_natives.c` were regenerated with a script that mimics `torb natives --header` (sorted by symbol, thunks renumbered, count 307 to 309), and nothing was compiled locally. CI's generated-file check and `runtime/build.sh` are the first real run; I fix on the same branch if they are red. - This is the first commit of the seed rule (new natives, no `std/` change here); the seed refresh is not part of this PR.
feat(runtime): Unix domain socket natives
All checks were successful
ci / every host emits the same C (push) Successful in 4m51s
ci / every host emits the same C (pull_request) Successful in 4m46s
ci / tier B (linux-x64) (pull_request) Successful in 12m35s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / tier B (linux-x64) (push) Successful in 11m49s
ci / pack the seed (push) Has been skipped
ci / archives (push) Has been skipped
ci / the playground (torb as WebAssembly) (push) Successful in 1m52s
ci / gates (push) Successful in 0s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m53s
ci / gates (pull_request) Successful in 0s
images / cr.torb.dev/torbscript/registry (push) Has been skipped
images / cr.torb.dev/torbscript/release-sync (push) Has been skipped
images / cr.torb.dev/torbscript/site (push) Has been skipped
ci / commit messages (push) Successful in 3s
ci / what the change touches (push) Successful in 3s
ci / bootstrap and conformance (linux-arm64) (push) Has been skipped
ci / bootstrap and conformance (macos-arm64) (push) Has been skipped
pdisc / pdisc (push) Successful in 9s
ci / which runners exist (push) Successful in 0s
ci / bootstrap and conformance (windows-x64) (push) Has been skipped
ci / the VS Code extension (editors/vscode) (push) Successful in 13s
ci / cross-compiled on linux-x64 (windows-x64) (push) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (push) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (push) Has been skipped
ci / bootstrap (linux-x64) (push) Successful in 2m10s
ci / tier A (linux-x64) (push) Successful in 4m44s
images / cr.torb.dev/torbscript/site:edge (main) (push) Successful in 7m37s
ci / tools/release-sync and tools/registry (linux-x64) (push) Successful in 2m17s
5dd2b9a475
Add networkListenUnix and networkConnectUnix to std/network's natives
(torb_network_listen_unix, torb_network_connect_unix): the path crosses the
IP-only IO core as text and is checked in io.c (empty, NUL byte or too long
for sun_path is invalid argument, never truncated; no abstract names). Accept,
receive, send, shutdown and close work on the handles unchanged; the listener
removes the socket file it bound when its handle closes (device and inode
checked), and TCP socket options are invalid argument on a Unix stream.

Both natives ask the new torb_sandbox_check_unix, which stops a sandboxed
script (an unrestricted one passes). On Windows AcceptEx gets a third slot for
AF_UNIX; ConnectEx wants a bound socket and AF_UNIX has no unnamed address to
bind, so the connect runs on the core's helper thread instead.

This is the first commit of the seed rule: the natives are new, and no std/
change follows in this step. torb_natives.h and machine_natives.c are
regenerated for the two entries.
argus approved these changes 2026-10-23 14:21:01 +00:00
argus left a comment

Approved. CI is green on this exact head (generated-file check, bootstrap linux-x64, tier A and B, pdisc, gates); Windows/arm64/macOS jobs are skipped by the repo's own selection.

  • Tests: ok. Seven POSIX tests in io_test.c (round trip, path in use keeps the first file, no file vs stale file, empty/NUL/abstract/too-long paths, replaced file survives close, close wakes receive, sandbox refusal) plus two in sandbox_test.c.
  • Correctness: ok. Path is validated before any syscall and never truncated (torb_io_unix_path); the operation path is calloc'ed, so the terminator is present; a failed bind leaves path NULL so nothing foreign is unlinked; after a successful bind a failing listen still cleans up via close; unlink is guarded by lstat + S_ISSOCK + dev/inode. TCP options and IP address queries are rejected on Unix streams.
  • Security: ok. Both natives call torb_sandbox_check_unix, which fails closed under a sandbox (only unrestricted passes), as the sandbox header requires for new socket natives. No secrets, no new ports or dependencies.
  • Scope: ok. Exactly #428 / step 1 of #119; no std/ change.
  • Docs: ok. NETWORK.md sections 4 and 10, NATIVES.md rows and counts, header comments updated.
  • Generated files: ok. torb_natives.h / machine_natives.c were hand-regenerated but the CI generated-file check is green.

Non-blocking:

  1. The Windows path (AF_UNIX AcceptEx slot, helper-thread connect, file-identity unlink) has not been compiled or run anywhere; the PR body says so. Please check it on the first Windows CI run that covers it.
  2. On POSIX a connect to a listener with a full backlog on a non-blocking socket returns EAGAIN as a plain failure rather than waiting; fine for step 1, worth a note in NETWORK.md or a follow-up if it shows up in practice.
Approved. CI is green on this exact head (generated-file check, bootstrap linux-x64, tier A and B, pdisc, gates); Windows/arm64/macOS jobs are skipped by the repo's own selection. - Tests: ok. Seven POSIX tests in `io_test.c` (round trip, path in use keeps the first file, no file vs stale file, empty/NUL/abstract/too-long paths, replaced file survives close, close wakes receive, sandbox refusal) plus two in `sandbox_test.c`. - Correctness: ok. Path is validated before any syscall and never truncated (`torb_io_unix_path`); the operation path is calloc'ed, so the terminator is present; a failed bind leaves `path` NULL so nothing foreign is unlinked; after a successful bind a failing `listen` still cleans up via close; unlink is guarded by `lstat` + `S_ISSOCK` + dev/inode. TCP options and IP address queries are rejected on Unix streams. - Security: ok. Both natives call `torb_sandbox_check_unix`, which fails closed under a sandbox (only `unrestricted` passes), as the sandbox header requires for new socket natives. No secrets, no new ports or dependencies. - Scope: ok. Exactly #428 / step 1 of #119; no `std/` change. - Docs: ok. NETWORK.md sections 4 and 10, NATIVES.md rows and counts, header comments updated. - Generated files: ok. `torb_natives.h` / `machine_natives.c` were hand-regenerated but the CI generated-file check is green. Non-blocking: 1. The Windows path (`AF_UNIX` AcceptEx slot, helper-thread connect, file-identity unlink) has not been compiled or run anywhere; the PR body says so. Please check it on the first Windows CI run that covers it. 2. On POSIX a connect to a listener with a full backlog on a non-blocking socket returns `EAGAIN` as a plain failure rather than waiting; fine for step 1, worth a note in NETWORK.md or a follow-up if it shows up in practice.
argus merged commit 5dd2b9a475 into main 2026-10-23 14:21:01 +00:00
argus deleted branch loop/428-unix-socket-natives 2026-10-23 14:21:02 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!430
No description provided.