So, I came across the ttyname function (unistd.h) and had to test it out.#include <unistd.h>#include <stdio.h>int main(void) {  printf(%s\n, ttyname(0));  return 0;}On my machine, it echos out /dev/ttys011. I discovered it's a device!echo Hello > /dev/ttys011Woah, running that from another terminal produced Hello in the original terminal I ran my ttyname program in.So what happens when I cat /dev/ttys011? Well, I get every other character typed. Oh yeah; it breaks the original TTY session, too.So I try the following:cat /dev/ttys011 | tee /dev/ttys011Well, everything shows up in the original terminal, but my tap terminal (the one the above command is being run in) is still only getting every other character.Oh yeah, my original terminal is still broken (the characters show up, but only every other character actually reaches my shell).For instance, typing ls yields ls in the terminal, l in the tap terminal, and running it gives me 'l' is not a command.What is going on here? I would expect weird behavior, but why is every other character being captured?
Why does tapping a TTY device only capture every other character?
devices;tty
Your shell, or whatever process was in the foreground, was already reading the terminal to which is was attached, which was /dev/ttys011. Then you started another process, a cat also reading the same terminal at the same time.Now there are two processes competing for the same input from the terminal. Each time you type a key in the terminal, it is delivered to one of the waiting processes. The other process is interested in reading too, but when it becomes its turn to read there's nothing left to read. Even though you seemed to observe a regular alternation of which characters go to which process, it's actually unpredictable which parts of the input will go to which process: it could be all input to one, all input to the other, or anything in between.If you want your cat process to receive all of the input, you need to arrange for nothing else to be reading from the same device at the same time. One easy way you could do that is to run something like sleep 999 in the terminal. sleep waits for the delay to expire, but while it's waiting it shouldn't be attempting to read anything.The command:cat /dev/ttys011 | tee /dev/ttys011does not restore any input captured by cat to its original location. That is, tee does not deliver it to whatever process was originally interested in reading it (such as your shell), it just sends it to the terminal's output, which causes it to be displayed.By the way: you don't need a C program and the ttyname() function to get your terminal's name; all you have to do is type tty and press enter at the shell prompt.