Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Terminals are weird, but it's not because of the data stream.

The real mind-bending weirdness is in the kernel tty layer, for historical performance reasons. Userspace apps weren't able to keep up with typing in the early days, so the kernel is expected to handle stuff like simple editting (^H) and line buffering. And it has to handle baud rate and uart settings, of course. And it has to trap "special" keys like ^C so that hung applications can be reliably terminated via a signal. And it has to detect dropped lines to free up the terminal for other users.

And it still does all this nonsense even in a world where those use cases are all forgotten.

Terminals are weird.

(But no, there aren't any other good alternatives, so we just deal with it.)



The tty layer handles line editing so that programmers do not have to replicate this functionality.

If you write a simple program that obtains commands using "fgets", you automatically get simple editing, and that functionality goes away when the input is redirected from some other device or file.

The simple editing is consistent from program to program and maintains the user's preferences.

The tty input editing could be done in user space, like in the C library (and in POSIX implementations on non-Unix kernels like Cygwin and whatnot, that seems to be where it is).

The mind-boggling complexity is in sessions, controlling terminals, POSIX job control, foreground and background process groups and such.

Plus the quirks: like Ctrl-D just means "return now from the system call", so it only signals EOF when typed on an empty line due to read returning zero. And on TTY's it's a recoverable condition:

   cat /dev/tty /dev/tty
   a
   b
   c
   [Ctrl-D] # first "EOF"
   d
   e
   f
   [Ctrl-D] # second "EOF


Well, sure. But in a sane modern architecture that simple editor would be implemented in a userspace app (the terminal emulator would be an obvious candidate) and speak a sane protocol instead of the ioctl madness we have with termios.

But it doesn't and it won't, so we all deal with it. But it remains crazy.


Bill Joy's vi (1978) was implemented in user space; that counts as ancient, just a couple of years after the first Unix release. The ioctl madness just has to be applied twice: to change to raw mode input when starting the editor, and then to restore the original mode when exiting or jumping to the shell. The tcsetattr and tcgetattr functions are very easy to use: get the structure, tweak a few things, set the structure.


Another thing is that SIGINT interruption (via Ctrl-C or whatever character is configured) and SIGHUP signals wouldn't be reliable if faked outside of the kernel.

Firstly, the tty driver can read and respond to a Ctrl-C even if the application is single-threaded and spinning in a loop, or blocked on some device other than the TTY. If Ctrl-C were handled in user space, then there would have to be a thread through which the terminal I/O goes. Secondly, that thread would have to be completely reliable, and never block or hang for any reason other than reading from the TTY.

Also, a security feature known as a SAK (secure attention key) needs to be in the kernel. A TTY which implements a SAK cannot be entirely transparent.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: