|
|
|
|
|
by jonnyasmar
37 days ago
|
|
The split-of-responsibilities point really shows up when you try to host a TUI inside a PTY you control. Spawning Claude Code, Codex, and other agents into terminal panes on macOS, I hit this chain of small surprises: - SIGWINCH doesn't always fire on initial spawn — the TUI starts up thinking it has 0 columns and emits garbage until the first real resize. Fix: synthesize an ioctl(TIOCSWINSZ) before the first read, and re-send on focus events.
- xterm.js negotiates dimensions with the PTY backend over a non-obvious dance; off-by-one in the cell math wraps long prompts in the wrong place every time.
- Tools that detect "am I in a TTY" via isatty() behave differently from tools that stat() stdin; a few agents fall through to non-TUI mode if the PTY's mode bits aren't quite right. None of that is reflected in the abstract "PTY is a virtual terminal" mental model. The kernel/terminal/application split is a leaky abstraction in practice — you only find out by hosting one inside the other. |
|
Wait, how do you even use fstat's output to find out if the file is a tty?
Although in my experience the "funniest" part is deciding whether to use isatty() on stdin or on stdout. I mean, there is no much point enabling line editing/tab completion if stdin is a pipe/regular file, right?