title: Working of dup3
body: <p>While reading dup3 system call, I got that it will change only O_CLOEXEC flag of duplicated file desriptor. But when I have written below program for all the 3 outputs it printed the flag is either present or not and it is based on whether O_CLOEXEC is specified in original file descriptor when opening. What's wrong ? I really don't understand.</p>
  
  <pre><code>#define _GNU_SOURCE
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;getopt.h&gt; 
  #include &lt;errno.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;string.h&gt;
  
  #define TRUE 1
  #define FALSE 0
  
  void PrintUsage();
  void PrintVersion();
  void PrintStatusCloexec( int );
  void dup3_code( const char * );
  
  void main(int argc, char *argv[])
  {
      int hflag = FALSE, vflag = FALSE, nflag = FALSE, src_flag = FALSE;
      char *src_file_name = NULL; 
      int src_len = 0;
      char c;
      int option_index;
  
      struct option long_options[] = { 
              { "version", no_argument, 0, 0},
              { "help", no_argument, 0, 0}, 
              { "src_file", required_argument, 0, 0},
              {0,0,0,0}
          };      
  
      while( ( c = getopt_long(argc, argv, "hvs:", long_options, &amp;option_index) ) != -1 )
      {
          switch( c )
          {
              case 'h':
                  hflag = TRUE;
                  break;
              case 'v':
                  vflag = TRUE;
                  break;
              case 's':
                  src_flag = TRUE;
                  src_len = strlen( optarg );
                  src_file_name = (char *)calloc(1, src_len + 1);
                  strncpy(src_file_name, optarg, src_len);
                  break;
              case 0:
                  switch(option_index)
                  {
                      case 0: vflag = TRUE;
                          break; 
                      case 1: hflag = TRUE;
                          break;
                      case 2: src_flag = TRUE;
                          src_file_name = (char *) calloc(1, strlen(optarg) + 1);
                          strncpy(src_file_name, optarg, src_len);
                          break;
                      default: printf(" Invalid argument index : %d", option_index );
                          exit(EXIT_FAILURE); 
                  }
                  break;
  
              case '?':
                  break;
              default:
                  printf( " Invalid option %c", c);
                  exit(EXIT_FAILURE);
          }
      }
  
      if( vflag == FALSE &amp;&amp; src_flag == FALSE ) 
      {
          PrintUsage();
      }
  
      if(hflag == TRUE)
      {
          PrintUsage();
      }
  
      if(vflag == TRUE )
      {
          PrintVersion();
      }
  
      if(src_flag == TRUE)
      {
          printf(" src file name : %s\n", src_file_name);
          dup3_code( src_file_name );
      }
  
      exit(EXIT_SUCCESS);
  }
  
  void PrintUsage()
  {
      printf(" Usage : %s [-h] [-v] [-s|src_file file_name]\n" , __FILE__ );
  }
  
  void PrintVersion()
  {
      printf(" Version : 1.0\n");
  }
  
  void dup3_code( const char *file_name )
  {
      int fd = open( file_name, O_RDWR | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
      if( fd == -1 )
      {
          printf(" Error opening file %s : %s\n", file_name, strerror(errno));
          exit(EXIT_FAILURE);
      }
      printf( "After file is opened:\n");
      PrintStatusCloexec( fd );
  
      int new_fd = dup( fd );
      printf( "After dup:\n" );
      PrintStatusCloexec( new_fd );
      close( new_fd );
  
      new_fd = dup3( fd, new_fd, O_CLOEXEC );
      printf( "After dup3:\n" );
      PrintStatusCloexec( new_fd );
      close( new_fd );
  
      close( fd );
  }
  
  void PrintStatusCloexec( int fd )
  {
      int flags = fcntl( fd, F_GETFL );
      if( flags &amp; O_CLOEXEC )
      {
          printf( " close on exec flag for file id %d is set\n", fd );
      }
      else
      {
          printf( " close on exec flag for file id %d is not set\n", fd );
      }
  
  }
  </code></pre>
  
  <p>Also My GNU C library version :</p>
  
  <pre><code>GNU C Library (Ubuntu EGLIBC 2.15-0ubuntu10) stable release version 2.15.
  </code></pre>