I have the following code:
char str = "Hello\n";
write(0, str, 6); // write() to STDIN
When I compiled and executed this program,
Hello was printed in the terminal.
Why did it work? Did
write() replace my
0 (STDIN) argument with
Well, old Unix systems were originaly used with serial terminals, and a special program
getty was in charge to manage the serial devices, open and configure them, display a message on an incoming connexion (break signal), and pass the opened file descriptors to login and then the shell.
It used to open the tty device as input/output to configure it, and that was then duplicated in file descriptors 0, 1 and 2. And by default the (still good old)
stty command operates by default on standard input. To ensure compatibility, on modern Linuxes, when you are connected to a terminal, file descriptor 0 is still opened for input/output.
It can be used as a quick and dirty hack to only display prompts when standard input is connected to a terminal, because if standard input is redirected to a read only file or pipe, all writes will fail (without any harm for the process) and nothing will be printed. But it is anyway a dirty hack: just imagine what happens if a caller passes a file opened for input/output as standard input… That’s why good practices recommend to use stderr for prompts or messages to avoid having them lost in redirected stream while keeping output and input in separate streams, which is neither harder nor longer.
TL/DR: if you are connected to a terminal, standard input is opened for input/output even if the name and standard usage could suggest it is read only.
Because by default your terminal will echo stdin back out to the console. Try redirecting it to a file; it didn’t actually write to stdout.
Are you confusing write with fwrite? The first parameter in write is a “file descripter”, but it’s not stdin. Try doing an fwrite to stdin — it doesn’t happen.