为什么close()系统调用刷新输出?

Din*_*esh 3 c unix dup

这是我的代码:

#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
int main(int argc,char *argv[])
{
  int oldfd;
  int newfd;
  if(argc!=2)
  {
    printf("Usgae : %s file_name\n",argv[0]);
    exit(0);
  }
 oldfd=open(argv[1],O_RDWR|O_APPEND,S_IRWXU); // Opening the file in Read/Write mode
 if (-1 == oldfd)
 {
  perror("Error opening file");
  exit(0);
 }
 close(1); // closing stdout 
 newfd=dup(oldfd); //Now this newfd holds the value 1 
 close(oldfd); //closing the oldfd
 printf("\nStack Overflow"); //Now this printf will print content into the file as stdout closed already
 close(newfd);// closing newfd 
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我实际上要做的就是使用printf()而不是write()系统调用将"Stack Overflow"打印到文件中.

它不会将内容打印到文件中.但我观察到的一件事是,如果我删除代码:

 close(newfd)
Run Code Online (Sandbox Code Playgroud)

它按预期将内容打印到文件中.但我不明白为什么.我打印了内容,然后我才关闭newfd.

这是什么原因?

Jef*_*tin 5

这里实际发生的是printf输出被缓冲而不是立即发送到fd 1; 而是在返回之后,C运行时将缓冲区刷新到文件描述符1 main.如果你close(newfd),你已经有效地阻止了自动冲洗,否则由退出时的运行时间执行.

如果您明确地fflush(stdout)在您之前close(newfd),您的输出应出现在文件中.

顺便说一句,如果你想重定向一个特定的文件描述符,有一个备用的系统调用dup2(oldfd, 1),它使fd 1成为副本oldfd,如果以前打开则关闭fd 1.