What is the practical difference, if any, between stdin
and STDIN_FILENO
in C?

- 63,008
- 17
- 141
- 172

- 619
- 1
- 6
- 7
-
2[An interesting discussion on the topic](http://www.rtems.com/ml/rtems-users/2011/march/msg00101.html). Perhaps you should also ask why `fileno(stdin)` differs from `STDIN_FILENO`. – user7116 Feb 27 '13 at 02:50
-
1@user7116 Your link is unfortunately dead. – Jonathon Reinhart Feb 27 '14 at 06:13
-
This link works http://www.rtems.org/ml/rtems-users/2011/march/thrd1.html#00101 – pixelbeat Mar 19 '14 at 01:10
-
1@pixelbeat your link is dead as well :( anyone have an informative read on the subject? – Jul 12 '14 at 17:21
-
rtems keep breaking links. Here's new location http://www.rtems.org/rtems/maillistArchives/rtems-users/2011/march/thrd1.html#00101 – pixelbeat Jul 13 '14 at 22:24
-
@pixelbeat link dead.. – Koray Tugay May 23 '15 at 15:19
-
1Latest link appears to be: https://lists.rtems.org/pipermail/users/2011-March/023277.html – David Arnold Aug 23 '16 at 23:29
-
6I am settling this matter once and for all: https://web.archive.org/web/20180127193256/https://lists.rtems.org/pipermail/users/2011-March/023277.html – lvella Jan 27 '18 at 19:37
5 Answers
The interface. Like everyone else has said, stdin
is a FILE *
as defined by the standard c library. You can use some of the higher level interfaces like fread
, fwrite
, and fprintf
. On the other hand, STDIN_FILENO
is just a file descriptor (almost certainly 0). This uses a slight lower level interface through the likes of read
and write
.

- 72,802
- 19
- 102
- 127

- 2,181
- 14
- 14
-
37None of the answers mention that `STDIN_FILENO` is a macro defined in `
`. At least for a POSIX compliant system, it's not just "almost certainly 0"; it's required to be defined as 0. Similarly, `STDOUT_FILENO` is 1 and `STDERR_FILENO` is 2. – Keith Thompson Apr 06 '15 at 20:32 -
1The `
` header [...] and the two constants `STDIN_FILENO` and `STDOUT_FILENO` are part of the POSIX standard [...]. This header contains function prototypes for many of the UNIX system services, such as the `read` and `write` functions that we call. The constants `STDIN_FILENO` and `STDOUT_FILENO` are defined in ` – Nabil Kadimi Sep 29 '18 at 19:12` and specify the file descriptors for standard input and standard output. These values are `0` and `1`, respectively, as required by POSIX.1, but we’ll use the names for readability. -- Source: Advanced Programming in the Unix ® Environment - 2nd edition page 9
stdin
is a default FILE pointer used to get input from none other than standard in.
STDIN_FILENO
is the default standard input file descriptor number which is 0
. It is essentially a defined directive for general use.

- 219,201
- 40
- 422
- 469

- 32,370
- 6
- 56
- 63
From /usr/include/stdio.h
,
/* Standard streams. */
extern struct _IO_FILE *stdin; /* Standard input stream. */
extern struct _IO_FILE *stdout; /* Standard output stream. */
extern struct _IO_FILE *stderr; /* Standard error output stream. */
/* C89/C99 say they're macros. Make them happy. */
#define stdin stdin
#define stdout stdout
#define stderr stderr
From /usr/include/unistd.h
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
Ex, stdin
(_IO_FILE
defined in /usr/include/libio.h
) is a structure data. STDIN_FILENO
is a macro constant, which points to a file descriptor used by kernel.
#include <stdio.h>
#include <unistd.h>
void
stdin_VS_STDIN_FILENO(void)
{
printf("stdin->_flags = %hd\n", stdin->_flags);
printf("STDIN_FILENO : %d\n", STDIN_FILENO);
}
int
main(void)
{
stdin_VS_STDIN_FILENO();
return 0;
}

- 991
- 10
- 14
stdin : 1. A file pointer (* FILE) 2. The file descriptor table holds its address when process is created. 3. present in /usr/include/stdio.h
STDIN_FILENO : 1. It is a macro 2. Its nothing but an array index of a file descriptor table (default 0). 3.present in /usr/include/unistd.h
Could be more clear by following code.
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("%d\t\t%p ----- ",STDIN_FILENO,stdin);
return 0;
}

- 39
- 1
- 7
The STDIN_FILENO in the linux header #include "unistd.h" is just a macro for 0 which stands for the stdin for the pipe, when you are using Linux pipe.
-
You're right, however (nitpick) pipes have nothing to do with this. The standard input is not always a pipe, for example `./command < some_file` in bash will not create a pipe. You can check whether it's a pipe or not by getting the pipe size: `fcntl(STDIN_FILENO, F_GETPIPE_SZ)` returns `-1` in this case. The same call returns `65536` (or another positive integer, ymmv) when stdin is a pipe (`cat some_file | ./command`) – Eric May 28 '22 at 11:11