Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are stdin and stdout actually the same file?

I am completely confused, is it possible that stdin, stdout, and stderr point to the same filedescriptor internally? Because it makes no difference in C if i want to read in a string from the console if I am using stdin as input or stdout.

read(1, buf, 200) works as read(0, buf, 200) how is this possible?

(0 == STDIN_FILENO == fileno(stdin),
1 == STDOUT_FILENO == fileno(stdout))

like image 837
Fernadiniho Avatar asked Jan 02 '23 02:01

Fernadiniho


2 Answers

When the input comes from the console, and the output goes to the console, then all three indeed happen to refer to the same file. (But the console device has quite different implementations for reading and writing.)

Anyway, you should use stdin/stdout/stderr only for their intended purpose; otherwise, redirections like the following would not work:

<inputfile myprogram >outputfile

(Here, stdin and stdout refer to two different files, and stderr refers to the console.)

like image 82
CL. Avatar answered Jan 05 '23 15:01

CL.


One thing that some people seem to be overlooking: read is the low-level system call. Its first argument is a Unix file descriptor, not a FILE* like stdin, stdout and stderr. You should be getting a compiler warning about this:

    warning: passing argument 1 of ‘read’ makes integer from pointer without a cast [-Wint-conversion]
   int r = read(stdout, buf, 200);
                ^~~~~~

On my system, it doesn't work with either stdin or stdout. read always returns -1, and errno is set to EBADF, which is "Bad file descriptor". It seems unlikely to me that those exact lines work on your system: the pointer would have to point to memory address 0, 1 or 2, which won't happen on a typical machine.

To use read, you need to pass it STDIN_FILENO, STDOUT_FILENO or STDERR_FILENO.

To use a FILE* like stdin, stdout or stderr, you need to use fread instead.

like image 42
Thomas Avatar answered Jan 05 '23 16:01

Thomas