Linx.Tty is the terminal surface for an interactive workload — the termios, /dev/tty, and PTY ioctl primitives plus the attach/2 byte pump that wires a stdio: :pty workload to the caller's terminal, giving the BEAM a docker attach experience.

Terminals are a coherent kernel concept: a line discipline, the controlling- terminal abstraction behind /dev/tty, the termios(3) struct, and the TIOC* ioctl(2) surface (notably window size). Linx.Process already knows how to give a workload its own PTY with stdio: :pty; Linx.Tty is the interactive layer that connects that PTY to a human. Its core verb, attach/2, puts the caller's terminal into raw mode and pumps bytes both ways — keystrokes in, program output out — restoring the terminal exactly on exit so a forgotten raw mode can't strand the user. It deliberately opens /dev/tty directly rather than the BEAM's group-leader-mediated stdio, the same way vim and less do, and forwards live SIGWINCH resizes through to the workload. It is not a shell, terminfo layer, or line editor — just the primitives a consumer builds those on.

Where it fits

Unlike Linx.User, Linx.Capabilities, and Linx.Seccomp — the checkpoint- window verbs that constrain a workload before execveLinx.Tty operates after proceed/1, on a running :pty workload. It is the post-launch counterpart: those subsystems decide what the process may do, Linx.Tty decides how a human talks to it. It pairs specifically with Linx.Process's stdio: :pty (the PTY allocation) and pty_set_winsize/2 (resize propagation); a terminal-in-the-browser or kubectl exec -it-style consumer is what drives it.

Flow

flowchart LR
    term["caller's terminal<br/>(/dev/tty or group leader)"]
    attach["Linx.Tty.attach/2<br/>raw mode · byte pump · SIGWINCH"]
    pty["workload's PTY<br/>(Process stdio: :pty)"]
    work[":pty workload<br/>bash · vim · top"]
    term -->|"keystrokes"| attach -->|"keystrokes"| pty --> work
    work -->|"output"| pty -->|"output"| attach -->|"output"| term

Learn more