AF_UNIX Sockets and SCM_RIGHTS
AF_UNIX sockets are the transport layer for nearly all local IPC on Linux. Combined with SCM_RIGHTS for fd passing, they enable zero-copy data transfer between processes — the architecture that makes Wayland fundamentally different from X11.
AF_UNIX Sockets and File Descriptor Passing
Kernel Foundation
WAYLAND_DISPLAY=wayland-1 tells clients the socket filename inside XDG_RUNTIME_DIR. The full path is:
/run/user/1000/wayland-1
This is a Unix domain socket where the Wayland compositor (Hyprland, Sway, etc.) listens. Wayland uses AF_UNIX with SOCK_STREAM — reliable, ordered, bidirectional, like TCP but local and without network overhead.
Socket Types in AF_UNIX
| Type | Semantics | Used By |
|---|---|---|
|
Reliable, ordered byte stream (like TCP) |
Wayland, D-Bus, PipeWire |
|
Unreliable, message-oriented (like UDP) |
systemd journal, syslog |
|
Reliable, message-oriented (preserves boundaries) |
Bluetooth HCI, some IPC protocols |
The Critical Kernel Feature: SCM_RIGHTS
The kernel feature that makes Wayland fundamentally different from X11 is fd passing via SCM_RIGHTS:
// Simplified -- how a client sends a buffer to the compositor
struct msghdr msg;
struct cmsghdr *cmsg;
cmsg->cmsg_type = SCM_RIGHTS; // "I'm passing a file descriptor"
sendmsg(wayland_fd, &msg, 0);
When wl-copy copies text to the clipboard:
-
wl-copyconnects to$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY(the socket) -
Sends a Wayland protocol message offering the clipboard data
-
When another app pastes, the compositor brokers an fd transfer — the pasting app gets a file descriptor it can
read()from
The kernel’s SCM_RIGHTS mechanism (net/unix/af_unix.c → unix_scm_to_skb()) enables zero-copy transfer. The compositor never copies the clipboard content itself — it passes file descriptors between processes. This is architecturally different from X11, where the X server held selection data in its own memory.
How fd Passing Works in the Kernel
-
Sender calls
sendmsg()withSCM_RIGHTScontrol message containing one or more file descriptors -
Kernel increments the reference count on each
struct filebeing passed (fget()) -
The fds are attached to the
sk_buff(socket buffer) traveling through the AF_UNIX transport -
Receiver calls
recvmsg()— kernel installs thestruct filepointers into the receiver’s fd table (fd_install()) -
The receiver now has its own fd pointing to the same underlying kernel object
The key insight: the file descriptors are not copied — the kernel object they reference is shared. Both processes end up with fds pointing to the same struct file, which points to the same inode or device. This is how DMA-BUF GPU buffers, shared memory regions, and clipboard data flow between processes without copying.
Kernel Source Map
| Source File | What It Does | Key Functions |
|---|---|---|
|
Socket connect/send/recv |
|
|
|
|
|
Control message structures |
|
|
Unix-specific SCM helpers |
|
Exploration Exercises
# Trace wl-copy's socket connection and fd passing
strace -e connect,sendmsg wl-copy <<< "test"
# See all AF_UNIX sockets on the system
ss -x
# Find which process owns the Wayland socket
ss -xlp | grep wayland
# Write a minimal AF_UNIX client in C (advanced)
# See: man 7 unix, man 2 socket, man 2 connect