stdin,stdout和stderr实际分配给标准输入和标准输出

时间:2013-12-13 09:59:19

标签: c stdout stdin kernighan-and-ritchie

我正在经历K&R。我对以下stdio.h的摘录感到困惑。

typedef struct _iobuf {
  int cnt;    /* characters left */
  char *ptr;  /* next character position */
  char *base; /* location of buffer */
  int flag;   /* mode of file access */
  int fd;     /* file descriptor */
} FILE;

extern FILE _iob[OPEN_MAX];

#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])

此处FILE被定义为结构,stdinstdoutstderr是类型FILE数组的前三个成员。那么(&_iob[0])(&_iob[1])(&_iob[2])standard input devicestandard output device的分配是在哪里编写的?

4 个答案:

答案 0 :(得分:1)

此处,_iob[OPEN_MAX];被声明为extern变量为extern FILE _iob[OPEN_MAX];。这意味着,_iob[OPEN_MAX];由其他一些代码填充,并且有一个初始代码,用于指定(&_iob[0]), (&_iob[1]) or (&_iob[2]) to stdin, stdout and stderr

答案 1 :(得分:1)

这项任务可能是由一些在main()之前运行的初始化代码进行的。

此代码 - 除其他外 - 应该将这些数组条目链接到各自的文件描述符,这些描述符已经由操作系统的加载程序打开。

答案 2 :(得分:0)

您可以尝试一种方法。在Windows下,我使用llvm-ojbdump搜索_iob相关符号。

llvm-objdmp -t libucrt.lib > symbol.txt

在文件symbol.txt中找到关键字“ _iob”,我发现了符号__acrt_iob_func,然后构造了用于验证的代码。

extern FILE* __acrt_iob_func(unsigned);
#define stdin  (__acrt_iob_func(0))
#define stdout (__acrt_iob_func(1))
#define stderr (__acrt_iob_func(2))

您可以使用其他工具来转储C库的符号,然后搜索所需的符号。

答案 3 :(得分:0)

我知道这个问题是在2013年提出的。也许它的作者已经知道答案了。但是,由于该主题是由于缺少已检查的正确答案而打开的,因此我将在这里保留观点。

我认为,即使重新实现了某些io函数,系统(Unix)的设备stdin,stdout和stderr与文件描述符之间的关联仍然保持不变。

所以,我认为这本书是解决这个问题的答案:

FILE _iob[OPEN_MAX] =  { /* stdin, stdout, stderr : */
{ 0, (char *) 0, (char *) 0, _READ, 0 },
{ 0, (char *) 0, (char *) 0, _WRITE, 1 },
{ 0, (char *) 0, (char *) 0, _WRITE | _UNBUF, 2 }};

每次发生读取或写入功能时,这些文件描述符都将传递给它们。而且,由于未重新实现这些功能(读取和写入),因此系统知道在何处连接这些文件描述符。