关于这三个标准输入输出,由于是从父进程继承下来的,在libc内并没有打开的过程,而是直接以 0/1/2
三个fd包装上 _IO_file_jumps
作为 vtable
,定义产生_IO_2_1_stdin_/_IO_2_1_stdout_/_IO_2_1_stderr_
, _IO_stdin/_IO_stdout/_IO_stderr
则是对应的 _IO_FILE
指针,最后再导出为 FILE *
类型的 stdin/stdout/stderr
// libio/stdfiles.c, line #61
# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \\
struct _IO_FILE_plus NAME \\
= {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \\
&_IO_file_jumps};
# endif
#endif
DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES);
DEF_STDFILE(_IO_2_1_stdout_, 1, &_IO_2_1_stdin_, _IO_NO_READS);
DEF_STDFILE(_IO_2_1_stderr_, 2, &_IO_2_1_stdout_, _IO_NO_READS+_IO_UNBUFFERED);
// libio/libio.h, line #315
extern struct _IO_FILE_plus _IO_2_1_stdin_;
extern struct _IO_FILE_plus _IO_2_1_stdout_;
extern struct _IO_FILE_plus _IO_2_1_stderr_;
#define _IO_stdin ((_IO_FILE*)(&_IO_2_1_stdin_))
#define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_))
#define _IO_stderr ((_IO_FILE*)(&_IO_2_1_stderr_))
// libio/stdio.c, line #30
#undef stdin
#undef stdout
#undef stderr
_IO_FILE *stdin = (FILE *) &_IO_2_1_stdin_;
_IO_FILE *stdout = (FILE *) &_IO_2_1_stdout_;
_IO_FILE *stderr = (FILE *) &_IO_2_1_stderr_;
#undef _IO_stdin
#undef _IO_stdout
#undef _IO_stderr
#ifdef _LIBC