Module sys/unix
Async Unix-domain sockets — the raw syscall boundary.
The AF_UNIX socket calls plus a sockaddr_un builder. The transfer
calls are the SAME externs std/sys/tcp uses — a connected socket is a
connected socket at the syscall layer — so this module exists for the
address family and the address construction, not for a different set of
operations. std/net/unix.yo is the public surface
(UnixStream, UnixListener).
Every operation returns an IoFuture resolving to a non-negative value
(an fd for socket_* and accept, a byte count for send/recv, 0 for
the rest) or a negative errno.
Stability
unstable — and Windows is a real capability question here, not a naming
one. Windows has had AF_UNIX since 2017 but implements neither
AcceptEx nor GetAcceptExSockaddrs for it, so the accept path in the
generated runtime has to take a separate route, and SOCK_DGRAM over
AF_UNIX does not exist there at all. UnixAddr also carries
std/sys/tcp's ownership problem in a slightly worse form — its buf is
an ?*u8 whose .None case means "the platform reported a zero-size
sockaddr_un", which is indistinguishable from "allocation refused" —
and abstract (Linux \0-prefixed) socket names cannot be expressed
through a NUL-terminated *u8 path at all. Freezing needs the Windows
matrix settled and an owning address type with a fallible constructor.
Types
A heap-allocated sockaddr_un buffer and its length.
Like std/sys/tcp's SockAddr it owns its allocation with no Dispose,
so every make_sockaddr_un needs a matching free_addr. buf is
optional because the constructor answers .None when the platform
reports a zero-size sockaddr_un, which is how a target without
Unix-domain sockets shows up.
Fields
| Name | Type | Description |
|---|---|---|
buf | ?(*(u8)) | The |
len | u32 | Size of the buffer in bytes — the |
Functions
Create a stream-oriented Unix-domain socket — socket(AF_UNIX, SOCK_STREAM, 0). Resolves to the new fd, or a negative errno. This is the
one to use: it is reliable, ordered and connection-based, like TCP but
without the network.
Returns: IoFuture
Create a datagram Unix-domain socket — socket(AF_UNIX, SOCK_DGRAM, 0).
Resolves to the new fd, or a negative errno.
Unlike UDP, AF_UNIX datagrams ARE reliable and ordered — the kernel
never drops them — so this is a message-boundary-preserving channel rather
than a lossy one. It does not exist on Windows.
Returns: IoFuture
Bind the socket to a filesystem path — POSIX bind(2). Resolves to 0, or
a negative errno.
This CREATES a socket file at the path, and -EADDRINUSE means the file
already exists — a stale one from a crashed process counts, so a server
normally unlinks the path (std/sys/dir's unlink) before binding.
Closing the socket does not remove the file; that is the owner's job too.
Access is governed by the directory's write permission, which is what
makes a socket in a mode-0700 directory a private channel.
Parameters
| Name | Type | Notes |
|---|---|---|
sockfd | i32 | |
addr | *u8 | |
addrlen | u32 |
Returns: IoFuture
Mark the socket as accepting connections — POSIX listen(2). Resolves to
0, or a negative errno. backlog bounds the pending-connection queue.
Parameters
| Name | Type | Notes |
|---|---|---|
sockfd | i32 | |
backlog | i32 |
Returns: IoFuture
Accept the next connection — POSIX accept(2). Resolves to the new
connection's fd, or a negative errno. addr/addrlen receive the peer's
address, which for a Unix socket is usually EMPTY (an unbound client has
no path), so do not rely on it to identify the caller — read the peer
credentials with SO_PEERCRED/LOCAL_PEERCRED through
std/sys/sockinfo if you need that.
Parameters
| Name | Type | Notes |
|---|---|---|
sockfd | i32 | |
addr | *u8 | |
addrlen | *u32 |
Returns: IoFuture
Connect to a bound Unix-domain path — POSIX connect(2). Resolves to 0,
or a negative errno; -ENOENT when nothing has bound the path and
-ECONNREFUSED when the file exists but no process is listening, which is
exactly the stale-socket-file case.
Parameters
| Name | Type | Notes |
|---|---|---|
sockfd | i32 | |
addr | *u8 | |
addrlen | u32 |
Returns: IoFuture
Send on a connected socket — POSIX send(2). Resolves to the number of
bytes accepted (which may be short on a SOCK_STREAM socket), or a
negative errno. The SIGPIPE caveat from std/sys/tcp's send applies
here too: the runtime does not ignore it.
Parameters
| Name | Type | Notes | Description |
|---|---|---|---|
sockfd | i32 | ||
buf | *u8 | The | |
len | usize | Size of the buffer in bytes — the | |
flags | i32 |
Returns: IoFuture
Receive on a connected socket — POSIX recv(2). Resolves to the number of
bytes read, or a negative errno. On a SOCK_STREAM socket 0 means the
peer closed; on a SOCK_DGRAM one it is a zero-length message.
Parameters
| Name | Type | Notes | Description |
|---|---|---|---|
sockfd | i32 | ||
buf | *u8 | The | |
len | usize | Size of the buffer in bytes — the | |
flags | i32 |
Returns: IoFuture
Close the descriptor — POSIX close(2). Resolves to 0, or a negative
errno. It does NOT unlink the socket file a bind created.
Parameters
| Name | Type | Notes |
|---|---|---|
fd | i32 |
Returns: IoFuture
Build a sockaddr_un for the filesystem path path (a NUL-terminated C
string). The caller must free_addr the result.
The path is copied into a fixed sun_path array — 104 bytes on macOS, 108
on Linux — and TRUNCATED to fit rather than reported as too long, so a
deep path silently binds somewhere else. .None comes back when the
platform reports a zero-size sockaddr_un.
Parameters
| Name | Type | Notes |
|---|---|---|
path | *u8 |
Returns: UnixAddr
Read the path out of a sockaddr_un buffer as a NUL-terminated C string.
The pointer BORROWS the buffer — it is sun_path's address inside it, not
a copy — so it dangles once the buffer is freed. An unbound peer's address
reads as an empty string.
Parameters
| Name | Type | Notes |
|---|---|---|
addr_buf | *u8 |
Returns: *u8