Selkie--App--Internal--Terminal
NAME
Selkie::App::Internal::Terminal - internal terminal cleanup role for Selkie::App
DESCRIPTION
Implementation detail composed by Selkie::App. It is not part of the stable 1.0 application API.
Captures the terminal's termios state before notcurses enters raw-style mode and restores it during shutdown. The capture/restore pair is implemented with in-process tcgetattr/tcsetattr NativeCall bindings rather than by shelling out to stty. Spawning a child process during shutdown proved fragile in two ways seen in the wild:
If the process's working directory has been deleted or renamed while the app was running,
posix_spawnfails with ENOENT before the command even runs ā thesttyrestore silently can't happen.A failed spawn surfaces as an
X::Proc::Unsuccessfulbroken on a thread-pool thread, which escapes a caller-sidetryand can propagate out ofSelkie::App.shutdown, skippingnotcurses_stopand the escape-sequence backstop entirely ā the exact wedged-terminal outcome the restore existed to prevent.
An in-process tcsetattr has neither failure mode: it needs no child process, no working directory, and reports failure via a return code.
The termios snapshot is treated as an opaque byte blob: tcgetattr fills it, tcsetattr replays it, and Selkie never interprets the fields. The buffer is comfortably larger than struct termios on every supported POSIX platform (glibc/musl Linux x86_64 + aarch64, macOS arm64), so one declaration serves all of them. On Windows there is no /dev/tty; every method gates on its existence and returns early, so the POSIX symbols are never resolved there.