dup2功能和程序行为

时间:2014-06-05 20:28:19

标签: c

如果我正在编写代码。

#include<stdio.h>
int main()
{
  int i;
  FILE *fp;
  fp=fopen("shiv.txt","w");
  printf("%d",fileno(fp));
  dup2(3,1);
  fprintf(fp,"hello");  
}

作为输出,程序正在hello3文件中打印shiv.txt

我们可以看到printf首先被调用,但其输出显示在fprintf的输出之后。

此外,在dup2语句后调用printf因此printf的输出应放在终端上

1 个答案:

答案 0 :(得分:1)

标准I / O流被缓冲 - 可能的例外是标准错误流,只有POSIX不需要完全缓冲。如果没有调用fflush(stdout)来刷新标准输出的输出缓冲区(或者如果它是行缓冲的那样,则是换行序列的输出),没有定义关于FILE接口的工作方式一旦你拨打dup2

由于dup2适用于文件描述符而不是FILE指针,因此您遇到了问题:POSIX没有指定在这种情况下要执行的操作。与stdout关联的缓冲区可能会被丢弃,也可能会像fclose一样被刷新。缓冲区甚至可以保持关联,而不是刷新/丢弃,因为从stdout接口的角度来看,FILE仍处于打开状态。

因此,如果不将FILE接口与基础文件描述同步,则行为不一定是确定性的(在fclose(stdout)之后添加dup2调用)。此外,除stderr stdout以及与您打开的文件的文件说明相关联的dup2之外,还会发生什么?行为是按dup2调用的顺序,与队列相反,还是与堆栈相反,甚至是看似随机的顺序,后者表明可能存在段错误?如果您dup2(STDERR_FILENO, STDOUT_FILENO),后跟dup2(fileno(fp), STDERR_FILENO),输出顺序是多少?写入标准输出/错误缓冲区的结果是出现在fprintf结果之前还是之后或混合(或有时是一个,有时是另一个)?哪个首先出现 - 写入stderr的数据或写入stdout的数据? 你能否确定这一切都会按顺序发生?

答案可能不会让您感到惊讶:不会。在一个配置上发生的情况可能与另一个配置上发生的情况不同,因为文件描述符,标准流使用的缓冲区和标准流的FILE接口之间的交互未定义。

正如@twalberg评论的那样,无法保证您打开的文件是文件描述符3,因此在对这样的数字进行硬编码时要小心。此外,您STDOUT_FILENO提供<unistd.h>,这是dup2实际声明的位置,因此您可以避免使用fileno来代替文件描述符1它