How does Terminal read from stdout and draw the text on-screen?
bash, c, linux, macos, unix
Solution
The magic part here that you don't seem to be aware of is the kernel's tty layer.
Each terminal window you open corresponds to a pseudoterminal device — for instance, `/dev/ttys001` is a name for one such device on Mac OS X. By default, any process that's running in a terminal and which doesn't have its input/output redirected from/to somewhere else, its standard input, output, and error are all set to one of these devices. For instance, if I run `lsof` on a `cat` process running in a terminal, I see:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
cat 52919 user 0u CHR 16,5 0t4562 3313 /dev/ttys005
cat 52919 user 1u CHR 16,5 0t4562 3313 /dev/ttys005
cat 52919 user 2u CHR 16,5 0t4562 3313 /dev/ttys005
When a process writes to a pseudoterminal slave device, the output is routed to the process holding the master end of the connection (in this case, your terminal application), which can read it. Similarly, when a terminal application writes to a pseudoterminal master device, the data becomes available to any process that's reading from the corresponding slave device.
There are a few other tricks involved with pseudoterminal devices. Most notably, they have an inherent size in rows and columns, which an application running in them can query, they can perform certain simple translations on data passing through them (for instance, CR to CR/LF, backspace to DEL, and other such things), and they can generate signals when certain characters are seen (e.g, Ctrl-C generates an interrupt signal to the foreground process). There's a lot of weird historical subtleties here, but the point is that the kernel's tty layer is where most of this behavior exists.
Pseudoterminal devices are created using the `forkpty()` libc function. The details of how this works behind the scenes vary from platform to platform, and can get pretty hairy, so I won't dig into the details.
Problem
I have a general question about how the terminal and processes work. From any process, if I write to stdout (i.e. file descriptor 2), it gets drawn on the terminal window. My question is, how is this actually implemented? Is stdout an actual 'dummy' file somewhere that the terminal keeps on reading from and drawing the content on screen? Or is there some kind of IPC between the process/stdout stream and the Terminal? Note that when I say terminal, I mean some general GUI terminal/console, such as Terminal on the Mac. P.S. If this question is unclear, let me know and I will happily try to explain again :) Thanks!