This source file includes following definitions.
- is_open
- is_inheritable
- zero
- is_mode
- main
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 #include <config.h>
  20 
  21 #include <unistd.h>
  22 
  23 #include "signature.h"
  24 SIGNATURE_CHECK (dup2, int, (int, int));
  25 
  26 #include <errno.h>
  27 #include <fcntl.h>
  28 
  29 #if HAVE_SYS_RESOURCE_H
  30 # include <sys/resource.h>
  31 #endif
  32 
  33 #include "binary-io.h"
  34 
  35 #if GNULIB_TEST_CLOEXEC
  36 # include "cloexec.h"
  37 #endif
  38 
  39 #if defined _WIN32 && ! defined __CYGWIN__
  40 
  41 # define WIN32_LEAN_AND_MEAN
  42 # include <windows.h>
  43 
  44 # if GNULIB_MSVC_NOTHROW
  45 #  include "msvc-nothrow.h"
  46 # else
  47 #  include <io.h>
  48 # endif
  49 #endif
  50 
  51 #include "macros.h"
  52 
  53 
  54 static int
  55 is_open (int fd)
     
  56 {
  57 #if defined _WIN32 && ! defined __CYGWIN__
  58   
  59 
  60 
  61   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
  62 #else
  63 # ifndef F_GETFL
  64 #  error Please port fcntl to your platform
  65 # endif
  66   return 0 <= fcntl (fd, F_GETFL);
  67 #endif
  68 }
  69 
  70 #if GNULIB_TEST_CLOEXEC
  71 
  72 static int
  73 is_inheritable (int fd)
     
  74 {
  75 # if defined _WIN32 && ! defined __CYGWIN__
  76   
  77 
  78 
  79   HANDLE h = (HANDLE) _get_osfhandle (fd);
  80   DWORD flags;
  81   if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
  82     return 0;
  83   return (flags & HANDLE_FLAG_INHERIT) != 0;
  84 # else
  85 #  ifndef F_GETFD
  86 #   error Please port fcntl to your platform
  87 #  endif
  88   int i = fcntl (fd, F_GETFD);
  89   return 0 <= i && (i & FD_CLOEXEC) == 0;
  90 # endif
  91 }
  92 #endif 
  93 
  94 #if !O_BINARY
  95 # define set_binary_mode(f,m) zero ()
  96 static int zero (void) { return 0; }
     
  97 #endif
  98 
  99 
 100 
 101 static int
 102 is_mode (int fd, int mode)
     
 103 {
 104   int value = set_binary_mode (fd, O_BINARY);
 105   set_binary_mode (fd, value);
 106   return mode == value;
 107 }
 108 
 109 int
 110 main (void)
     
 111 {
 112   const char *file = "test-dup2.tmp";
 113   char buffer[1];
 114   int bad_fd = getdtablesize ();
 115   int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);
 116 
 117   
 118   ASSERT (STDERR_FILENO < fd);
 119   ASSERT (is_open (fd));
 120   
 121   close (fd + 1);
 122   close (fd + 2);
 123   ASSERT (!is_open (fd + 1));
 124   ASSERT (!is_open (fd + 2));
 125 
 126   
 127   ASSERT (dup2 (fd, fd) == fd);
 128   ASSERT (is_open (fd));
 129 
 130   
 131   errno = 0;
 132   ASSERT (dup2 (-1, fd) == -1);
 133   ASSERT (errno == EBADF);
 134   close (99);
 135   errno = 0;
 136   ASSERT (dup2 (99, fd) == -1);
 137   ASSERT (errno == EBADF);
 138   errno = 0;
 139   ASSERT (dup2 (AT_FDCWD, fd) == -1);
 140   ASSERT (errno == EBADF);
 141   ASSERT (is_open (fd));
 142 
 143   
 144   errno = 0;
 145   ASSERT (dup2 (fd + 1, fd + 1) == -1);
 146   ASSERT (errno == EBADF);
 147   ASSERT (!is_open (fd + 1));
 148   errno = 0;
 149   ASSERT (dup2 (fd + 1, fd) == -1);
 150   ASSERT (errno == EBADF);
 151   ASSERT (is_open (fd));
 152 
 153   
 154   errno = 0;
 155   ASSERT (dup2 (fd, -2) == -1);
 156   ASSERT (errno == EBADF);
 157   if (bad_fd > 256)
 158     {
 159       ASSERT (dup2 (fd, 255) == 255);
 160       ASSERT (dup2 (fd, 256) == 256);
 161       ASSERT (close (255) == 0);
 162       ASSERT (close (256) == 0);
 163     }
 164   ASSERT (dup2 (fd, bad_fd - 1) == bad_fd - 1);
 165   ASSERT (close (bad_fd - 1) == 0);
 166   errno = 0;
 167   ASSERT (dup2 (fd, bad_fd) == -1);
 168   ASSERT (errno == EBADF);
 169 
 170   
 171   ASSERT (dup2 (fd, fd + 2) == fd + 2);
 172   ASSERT (is_open (fd));
 173   ASSERT (!is_open (fd + 1));
 174   ASSERT (is_open (fd + 2));
 175 
 176   
 177   ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1);
 178   ASSERT (dup2 (fd + 1, fd) == fd);
 179   ASSERT (close (fd + 1) == 0);
 180   ASSERT (write (fd, "1", 1) == 1);
 181   ASSERT (dup2 (fd + 2, fd) == fd);
 182   ASSERT (lseek (fd, 0, SEEK_END) == 0);
 183   ASSERT (write (fd + 2, "2", 1) == 1);
 184   ASSERT (lseek (fd, 0, SEEK_SET) == 0);
 185   ASSERT (read (fd, buffer, 1) == 1);
 186   ASSERT (*buffer == '2');
 187 
 188 #if GNULIB_TEST_CLOEXEC
 189   
 190   ASSERT (close (fd + 2) == 0);
 191   ASSERT (dup_cloexec (fd) == fd + 1);
 192   ASSERT (!is_inheritable (fd + 1));
 193   ASSERT (dup2 (fd + 1, fd + 1) == fd + 1);
 194   ASSERT (!is_inheritable (fd + 1));
 195   ASSERT (dup2 (fd + 1, fd + 2) == fd + 2);
 196   ASSERT (!is_inheritable (fd + 1));
 197   ASSERT (is_inheritable (fd + 2));
 198   errno = 0;
 199   ASSERT (dup2 (fd + 1, -1) == -1);
 200   ASSERT (errno == EBADF);
 201   ASSERT (!is_inheritable (fd + 1));
 202 #endif
 203 
 204   
 205 
 206   set_binary_mode (fd, O_BINARY);
 207   ASSERT (is_mode (fd, O_BINARY));
 208   ASSERT (dup2 (fd, fd + 1) == fd + 1);
 209   ASSERT (is_mode (fd + 1, O_BINARY));
 210   set_binary_mode (fd, O_TEXT);
 211   ASSERT (is_mode (fd, O_TEXT));
 212   ASSERT (dup2 (fd, fd + 1) == fd + 1);
 213   ASSERT (is_mode (fd + 1, O_TEXT));
 214 
 215   
 216   ASSERT (close (fd + 2) == 0);
 217   ASSERT (close (fd + 1) == 0);
 218   ASSERT (close (fd) == 0);
 219   ASSERT (unlink (file) == 0);
 220 
 221   return 0;
 222 }