Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why close() system call flushing the output?

Tags:

c

unix

dup

Here is my code:

#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;
}

What I'm actually trying to do is just printing "Stack Overflow" to the file using printf() instead of write() system call.

Its not printing the content into the file. But one thing i observed is that if i remove the code:

 close(newfd)

It's printing the contents into the file as expected. But I can't understand why. I printed the contents and then only I'm closing the newfd.

Whats the reason for this?

like image 288
Dinesh Avatar asked Oct 15 '25 19:10

Dinesh


1 Answers

What's actually happening here is that printf's output is buffered and not sent to fd 1 immediately; instead the buffer is flushed to file descriptor 1 by the C run-time after you return from main. If you close(newfd), you've effectively obstructed the automatic flush that is otherwise performed by the run-time at exit.

If you explicitly fflush(stdout) before you close(newfd), your output should appear in the file.

By the way, if you want to redirect a specific file descriptor, there is an alternate system call dup2(oldfd, 1) which makes fd 1 a duplicate of oldfd, closing fd 1 if it was previously open.

like image 124
Jeffrey Hantin Avatar answered Oct 18 '25 11:10

Jeffrey Hantin