3
votes

I found this awesome text explaining a lot about TTY devices. It focuses in the relation between a TTY device and a shell (and its spawned jobs). But it says little about the relation between the terminal emulator and the TTY device; and now I'm wondering about that. I googled, but I could not find the answers...

1) What kind of input logic is the terminal emulator responsible for? It just sends each character code (received by window event) to the TTY device, or it does a more complicated processing before/during the transmission to the TTY? And how these character codes are sent to the TTY device? Via file?

2) After a foreground process calling write() to the TTY device file, a.k.a. stdout/stderr, what happens? How this data reaches the terminal emulator process, so it can be rendered? Again, via file?

3) Is the terminal emulator responsible for "allocating" a TTY device? TTY devices can be created "on the fly" by the kernel, or is there a limited number of available TTY devices the kernel can manage?

1
Via pseudoterminal (pty) devices. The linked article mentions them briefly but they are central to your question, so you may want to look for a more thorough explanation. Start by googling "pty".n. 1.8e9-where's-my-share m.

1 Answers

3
votes

First of all, answer yourself what a terminal is.

Historically, terminal devices where some dumb devices that transformed output characters from programs to visible drawings in some output device (a printer or a cathode ray tube) and send input characters to programs (produced at a keyboard locally) through a serial line.

From that perspective, a terminal emulator is some software application, normally running at a computer that has not been designed to act as a terminal device to make it behave as such. Normally, this means it will be receiving input from a serial line to output to the user (for example in a specific window on the screen) and will process user input on that window and send it to a remote computer for processing in the program running there.

By contrast, tty lines were serial lines used to send and receive characters. In UNIX, they used to have a common driver, that did some processing to the received characters from the actual terminal. For example, the unix driver collects all characters, allowing some editing via the use of the backspace key, and only make this data available to the program running on the computer after the user (the terminal) has sent the RETURN key.

Some time ago, the need to have virtual terminal devices (devices that don't have an actual terminal behind, but another program instead) where needed to run several programs that used to program the connecting device (for example, to not echo password characters back to the terminal, or to do character by character input, instead of line by line) and to allow the driving programs in the virtual TTY program to act upon these programmings.

Virtual terminal devices come in pairs and terminal emulating programs get the master side of the virtual terminal, running the actual program in the slave part (for example a login shell to allow a windows based pseudoterminal)

Now the answers to your questions:

1) Terminal input logic is managed at the virtual terminal driver of the slave device, as if the program running on it has complete control of character mapping or line/raw input. By the way, the program attached to the master side, only gets the raw characters, without any interpretation, so it can, for example, send a Control-C character to interrupt the program running on the slave side.

2) when the program running at the slave side does a write, this write goes through the tty driver, that makes all the asumptions of line-discipline (for example to add a CR char before any LF character to make a CRLF sequence, in case of terminal cooked mode of operation) the program running on the master side will receive the raw characters (even, for example a Ctrl-C written by the program) On input, tty device converts input character (case of a Ctrl-C) and sends the proper signal to the group of processes attached to that pseudo terminal.

3) Historically, the terminals appeared as device pairs (as one specific kind of terminal character device driver), and as such, they had inodes with major/minor number pairs. This limited their number to a properly configured administration value. Nowadays, linux, for example, allows dynamic allocation of devices, making it possible to allocate device pairs dynamically. But the maximum number continues to be bounded (for eficiency and implementation reasons)