2

The way I understand it, applications that create a pty (a master/slave pair) can be separated into 2 categories:

  • terminal emulators (xterm, urxvt, ...), which supposedly produce graphical output
  • the rest (docker, ssh, tmux, screen, ...), which supposedly produce text output

Meaning, the former have to more or less draw on a graphical display. The latter, produce text output (optionally with escape sequences) for the former. And what you supposedly get is a chain of terminal emulators (e.g. xterm <-> ssh <-> tmux <-> docker). Where the segments of the chain sort of translate escape sequences from one language to another. Or to be more precise, they process their escape sequences, and use the terminfo database to translate them to the next terminal emulator.

The following image from "The TTY demystified" is probably also in order here:

Now, what makes xterm xterm? Is it xterm that processes escape sequences, or it just lets the kernel do the work? In other words, the xterm terminfo database entry... does it correspond to the kernel, or to xterm? Well, putting it this way, the answer seems obvious. Although I still don't know if the kernel somehow affects the terminfo database entries.

What about the other programs? Is creating a pty gives you, sort of, a blank terminal that doesn't process escape sequences, and you're responsible for adding that sort of processing? Which means that the escape sequences you process determines the value of the TERM variable on the other end? Anything I'm missing here?

The question is inspired by the following answer, where the author claims that the TERM value doesn't matter.

1 Answer 1

1

The image is correct. The kernel (at least within the context of this question) does not act as a terminal emulator. It handles the line discipline, see the stty(1) and termios(3) manuals to have a feeling what the line discipline means. It's stuff like CR-LF conversion, ^C (interrupt) handling, some minimal line editing capabilities (called the "cooked" mode, which implements the handling of backspace, ^W and friends if you execute a command like cat which does not have its own line editing capabilities, and only sends the entire line when you press Enter), control flow, serial port properties (pretty much obsolete), stuff like these. But it doesn't handle the \e escape character.

Now, the Linux kernel does implement a terminal emulator, analogously to the "xterm" node of the image. It's the virtual console (typically on Ctrl+Alt+F1 and friends), the vt component of the Linux kernel rather than the tty component. For the purpose of this question, this is irrelevant; and I also see that your question is not speicific to Linux, I'm not familiar with other Unix variants in this regard.

Is it xterm that processes escape sequences, or it just lets the kernel do the work?

It is xterm. Overly simplified story: When xterm starts up, it sets up a tty line (master and slave side), fires up a command (typically a shell, "user process" in the picture, with TERM being set properly) connected to this tty and also presents a graphical window with the cursor at the upper left corner. Then it does a two-way communication.

For keypresses it transfers their sequences as seen in the arrows of the picture. Depending on the line discipline, the kernel might handle it itself (e.g. if you're running cat and press the letter 'x', it is not yet sent to cat, it's the kernel handling the basic line editing), in this case the kernel will tell the terminal how to update the display (probably by printing an 'x'); or it may forward the keypress to the relevant user process(es).

In the other direction, the user process may or may not want to update its display (and it may want to do it regardless of a received keypress), which data traverses this path in the opposite direction.

Let's say an app outputs x\e[31my\n. The line discipline converts \n to \r\n (otherwise you'd end up with the "staircase effect"), but it doesn't care about the \e character, so the terminal emulator receives x\e[31my\r\n.

xterm receives this and says: I need to print an x at the cursor, then \e[31m means I need to switch to red, then print a y (in red), then move the cursor back and down one line. It does so and updates its display accordingly.

In other words, the xterm terminfo database entry... does it correspond to the kernel, or to xterm?

Terminfo describes the behavior of various terminal emulators towards user applications (because all terminal emulators handle the escape sequences somewhat differently). The kernel doesn't know anything about it.

There's a slight overlap though with the kernel and what the terminfo says, e.g. the terminfo might contain an entry for the backspace character (whether it's ^H or ^?), but this behavior is implemented in the line discipline rather than the terminal emulator. The terminal emulator should configure the line discipline accordingly, and in this sense it's valid to say that it describes the terminal emulator's behavior, even though it's not the terminal emulator itself but it delegates this task to the kernel's line discipline. Anyway, I digress, this is the exception and not the rule. The rule is that terminfo describes the terminal emulator's own behavior.

Do programs that create pseudoterminals emulate terminals?

No, not necessarily. I would categorize apps that create a terminal line like this:

  • terminal emulators (xterm, urxvt, screen, tmux, ...)
  • not terminal emulators (ssh (when interactive or -t is given), script, luit, ...)

I'm not familiar with docker but I suspect it belongs to the second group.

The second group contains apps that by their very nature need to create a tty line, but only for the purpose of forwarding or logging or simple manipulation of the data that has nothing to do with escape sequences. These apps don't know what \e means, don't know that \e[31m means red, don't even know what "red" means, don't have a concept how the terminal's canvas should look like at a given moment.

The first group is apps that do have to care about such escape sequences. screen and tmux might be surprising at first, but these apps have absolutely no chance of implementing their behavior by just blindly forwarding the data - they wouldn't be able to restore the canvas when you reattach or switch between tabs, let alone handle a paned layout of multiple terminals at once. These tools have to parse and perfectly understand every escape sequence, and track in their memory how exactly the canvas needs to look like.

I prefer to think of screen and tmux as terminal emulators, with the main difference from xterm and friends being that their backend, their canvas on which they present the contents to the user, is the character grid of another terminal emulator, rather than a window's pixels on the graphical user interface. (The other main difference is the ability to detach and reattach, which is irrelevant here.)

I hope this all makes sense.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .