# Unix Domain Sockets
Linux/Android `AF_UNIX` stream socket primitives: bind, listen, accept, connect,
chmod for filesystem sockets, peer credentials, and byte I/O through `fd::Fd`.
Callers own all protocol, message framing, authentication policy, daemon
behavior, and socket naming. Core provides the mechanics only.
## Addresses
`UnixSocketAddr` distinguishes the two `AF_UNIX` address families:
- `Path(&Path)` — filesystem pathname socket.
- `Abstract(&[u8])` — Linux/Android abstract namespace name, *without* the
leading NUL. Interior NUL bytes in the caller-provided abstract name are
preserved by the kernel (explicit `sun_path` length).
Abstract sockets are Linux/Android-only.
## Listener
`UnixListener` is a bound, listening socket. `bind(addr, opts)` is a module-level
free function (not a `UnixListener` method) that creates the listener, applies the
stale-path policy, and calls `listen(SOMAXCONN)` — the returned listener is
already listening.
- `UnixSocketBindOptions` — the options carry `stale_socket_policy` and an
optional `mode` applied after a successful bind. Abstract addresses reject any
policy other than `Preserve` and any `Some(mode)` with `EINVAL`.
- `accept()` — non-blocking; returns `Ok(None)` when no client is ready.
`EAGAIN`/`EWOULDBLOCK`, `ECONNABORTED`, `EMFILE`, `ENFILE` documented on the
method.
- `accept_timeout(timeout_ms)` — `-1` blocks forever, `0` polls immediately,
`>0` waits that many ms via `poll(POLLIN)`. A `poll` `EINTR` returns
`Ok(None)` (not retried); an `accept4` `EINTR` is retried.
**Stale socket policy** (`StaleSocketPolicy`):
- `Preserve` (default) — leave any existing path and let `bind` report the
conflict.
- `UnlinkSocketOnly` — unlink only if the existing path is itself a socket.
- `UnlinkAnyPath` — unlink any existing path; may delete non-socket files, use
only when the caller owns the path namespace.
## Stream
`UnixStream` is a connected socket.
- `connect(addr)` returns a `UnixConnectResult`: `Connected(stream)` for an
immediate connect, or `InProgress(stream)` for a non-blocking connect in
progress. `finish_connect()` completes it; `check_connect_error()` reports
the deferred error. `EALREADY` maps to `InProgress`, `EISCONN` to `Connected`.
- `connect_named(remote, local)` — same as `connect`, but the client socket is
first bound to `local` so the connection appears in `/proc/net/unix` with a
caller-chosen name. The second argument is a full `UnixSocketAddr`, **not** a
bind-options struct.
- `peer_cred()` — `SO_PEERCRED`: `PeerCred { pid: Option<i32>, uid, gid }`
(always `Some` with `pid: Some` on Linux/Android; `Ok(None)` with no syscall
elsewhere).
- `socketpair()` — a connected pair of `UnixStream`s.
- `chmod(addr, mode)` / `chmod_path(path, mode)` — adjust a filesystem socket's
permissions; `Abstract` addresses and non-socket paths return `EINVAL`.
`Fd` (in `fd`) provides the byte I/O: `read_slice`, `write_slice`,
`read_u64_blocking`, and friends.
## Integration
Listeners and streams are registered with a `reactor::Reactor` via their
underlying `Fd` (`add_with_flags`). Accept/read are non-blocking and must be
drained until `EAGAIN` under the edge-triggered contract.