你为什么要复制filedescriptor而从不使用它?

时间:2015-01-05 23:19:15

标签: c shell unix

以下是部分:

extern fin;
char line[64];

if (argc<2 || ttyn(0)!='x') {
        write(1, "goto error\n", 11);
        seek(0, 0, 2);
        return;
}
seek(0, 0, 0);
fin = dup(0);

请注意,在整个代码中&#34; fin&#34;仅发生在上面的部分。 那么为什么要复制标准输入 (在这种情况下是文件/脚本), 将其存储在fin中并且从不使用它?

您可以在此处找到整个代码http://v6shell.org/history/goto.c,其中包含语法 - 突出显示http://pastebin.com/uAvANLdR

PS。这是K&amp; R-C。使用的命令dup在此处描述:http://man.cat-v.org/unix-6th/2/dup

更新 我发现,命令getchar实际上需要它。看这里http://man.cat-v.org/unix-6th/3/getchar

但我仍然不明白为什么你需要它。有人能说出来吗?

2 个答案:

答案 0 :(得分:3)

如果你看一下getchar(3)的手册页

http://man.cat-v.org/unix-6th/3/getchar

有一个小块说明:

  

与此例程相关联的是一个名为的外部变量   fin,是一个包含缓冲区的结构   在getc(III)下描述。

所以如果我们仔细看看getc(3)

http://man.cat-v.org/unix-6th/3/getc

我们看到了:

struct buf {
  int fildes;     /* File descriptor    */
  int nleft;      /* Chars left in buffer */
  char *nextp;    /* Ptr to next character */
  char buff[512]; /* The buffer */
};

goto.c中的代码现在通过告诉编译器&#34; fin&#34;是int类型。实际上&#34; fin&#34;具有类型struct buf,但是&#34; int filedes;&#34;是结构的第一个成员,代码执行实际上与:

相同
extern struct buf fin;

...

seek(0, 0, 0);
fin.fildes = dup(0);

正如我所说,这是一个hacky解决方案,但代码似乎已经很老了,其中包含了所有内容。

答案 1 :(得分:1)

我能想到的一个原因是,如果fd 0(stdin)是管道(2)的读取端并且稍后关闭(即在调用execve(2)之后),那么任何人都试图写入管道仍将被阻止,并且不会收到SIGPIPE信号。