The magic part here that you don't seem to be aware of is the tty core layer.
Each open terminal window corresponds to a pseudo-terminal device - for example, /dev/ttys001 is the name for one such device in Mac OS X. By default, any process that runs on the terminal and which does not have its input / output redirected from / to another location, its standard input, output, and error are installed on one of these devices. For example, 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 is written to a pseudo-terminal slave, the output is sent to a process that supports the main end of the connection (in this case, your terminal application), which can read it. Similarly, when a terminal application writes to a pseudo-terminal master, data becomes available for any process that is read from the corresponding slave.
There are several other tricks associated with pseudo-terminal devices. In particular, they have their own size in rows and columns, to which the application running in them can be run, they can perform some simple translations of the data passing through them (for example, CR in CR / LF, backspace to DEL and other similar things) , and they can generate signals when certain characters are visible (for example, Ctrl - C generates an interrupt signal for the foreground process). There are many strange historical subtleties, but the fact is that the tty layer of the kernel is where most of this behavior exists.
Pseudo-terminal devices are created using the forkpty() libc function. Details of how this works behind the scenes vary from platform to platform and can be quite hairy, so I wonβt go into details.
duskwuff
source share