This source file includes following definitions.
- zero
 
- is_open
 
- is_inheritable
 
- is_mode
 
- func1
 
- func2
 
- check_flags
 
- 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 
  22 #include <fcntl.h>
  23 
  24 #include "signature.h"
  25 SIGNATURE_CHECK (fcntl, int, (int, int, ...));
  26 
  27 
  28 #include <errno.h>
  29 #include <stdarg.h>
  30 #include <stdbool.h>
  31 #include <unistd.h>
  32 
  33 #if defined _WIN32 && ! defined __CYGWIN__
  34 
  35 # define WIN32_LEAN_AND_MEAN
  36 # include <windows.h>
  37 
  38 # if GNULIB_MSVC_NOTHROW
  39 #  include "msvc-nothrow.h"
  40 # else
  41 #  include <io.h>
  42 # endif
  43 #endif
  44 
  45 #include "binary-io.h"
  46 #include "macros.h"
  47 
  48 #if !O_BINARY
  49 # define set_binary_mode(f,m) zero ()
  50 static int zero (void) { return 0; }
     
  51 #endif
  52 
  53 
  54 static bool
  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 
  71 static bool
  72 is_inheritable (int fd)
     
  73 {
  74 #if defined _WIN32 && ! defined __CYGWIN__
  75   
  76 
  77 
  78   HANDLE h = (HANDLE) _get_osfhandle (fd);
  79   DWORD flags;
  80   if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
  81     return false;
  82   return (flags & HANDLE_FLAG_INHERIT) != 0;
  83 #else
  84 # ifndef F_GETFD
  85 #  error Please port fcntl to your platform
  86 # endif
  87   int i = fcntl (fd, F_GETFD);
  88   return 0 <= i && (i & FD_CLOEXEC) == 0;
  89 #endif
  90 }
  91 
  92 
  93 
  94 static bool
  95 is_mode (int fd, int mode)
     
  96 {
  97   int value = set_binary_mode (fd, O_BINARY);
  98   set_binary_mode (fd, value);
  99   return mode == value;
 100 }
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 struct dummy_struct
 111 {
 112   long filler;
 113   int value;
 114 };
 115 static int
 116 func1 (int a, ...)
     
 117 {
 118   va_list arg;
 119   int i;
 120   va_start (arg, a);
 121   if (a < 4)
 122     i = va_arg (arg, int);
 123   else
 124     {
 125       struct dummy_struct *s = va_arg (arg, struct dummy_struct *);
 126       i = s->value;
 127     }
 128   va_end (arg);
 129   return i;
 130 }
 131 static int
 132 func2 (int a, ...)
     
 133 {
 134   va_list arg;
 135   void *p;
 136   va_start (arg, a);
 137   p = va_arg (arg, void *);
 138   va_end (arg);
 139   return func1 (a, p);
 140 }
 141 
 142 
 143 
 144 static void
 145 check_flags (void)
     
 146 {
 147   switch (0)
 148     {
 149     case F_DUPFD:
 150 #if F_DUPFD
 151 #endif
 152 
 153     case F_DUPFD_CLOEXEC:
 154 #if F_DUPFD_CLOEXEC
 155 #endif
 156 
 157     case F_GETFD:
 158 #if F_GETFD
 159 #endif
 160 
 161 #ifdef F_SETFD
 162     case F_SETFD:
 163 # if F_SETFD
 164 # endif
 165 #endif
 166 
 167 #ifdef F_GETFL
 168     case F_GETFL:
 169 # if F_GETFL
 170 # endif
 171 #endif
 172 
 173 #ifdef F_SETFL
 174     case F_SETFL:
 175 # if F_SETFL
 176 # endif
 177 #endif
 178 
 179 #ifdef F_GETOWN
 180     case F_GETOWN:
 181 # if F_GETOWN
 182 # endif
 183 #endif
 184 
 185 #ifdef F_SETOWN
 186     case F_SETOWN:
 187 # if F_SETOWN
 188 # endif
 189 #endif
 190 
 191 #ifdef F_GETLK
 192     case F_GETLK:
 193 # if F_GETLK
 194 # endif
 195 #endif
 196 
 197 #ifdef F_SETLK
 198     case F_SETLK:
 199 # if F_SETLK
 200 # endif
 201 #endif
 202 
 203 #ifdef F_SETLKW
 204     case F_SETLKW:
 205 # if F_SETLKW
 206 # endif
 207 #endif
 208 
 209     default:
 210       ;
 211     }
 212 }
 213 
 214 int
 215 main (int argc, char *argv[])
     
 216 {
 217   if (argc > 1)
 218     
 219     return (is_open (10) ? 42 : 0);
 220 
 221   const char *file = "test-fcntl.tmp";
 222   int fd;
 223   int bad_fd = getdtablesize ();
 224 
 225   
 226   ASSERT (func2 (1, 2) == 2);
 227   ASSERT (func2 (2, -2) == -2);
 228   ASSERT (func2 (3, 0x80000000) == 0x80000000);
 229   {
 230     struct dummy_struct s = { 0L, 4 };
 231     ASSERT (func2 (4, &s) == 4);
 232   }
 233   check_flags ();
 234 
 235   
 236 
 237   fd = creat (file, 0600);
 238   ASSERT (STDERR_FILENO < fd);
 239   close (fd + 1);
 240   close (fd + 2);
 241 
 242   
 243   errno = 0;
 244   ASSERT (fcntl (-1, F_DUPFD, 0) == -1);
 245   ASSERT (errno == EBADF);
 246   errno = 0;
 247   ASSERT (fcntl (fd + 1, F_DUPFD, 0) == -1);
 248   ASSERT (errno == EBADF);
 249   errno = 0;
 250   ASSERT (fcntl (bad_fd, F_DUPFD, 0) == -1);
 251   ASSERT (errno == EBADF);
 252   errno = 0;
 253   ASSERT (fcntl (-1, F_DUPFD_CLOEXEC, 0) == -1);
 254   ASSERT (errno == EBADF);
 255   errno = 0;
 256   ASSERT (fcntl (fd + 1, F_DUPFD_CLOEXEC, 0) == -1);
 257   ASSERT (errno == EBADF);
 258   errno = 0;
 259   ASSERT (fcntl (bad_fd, F_DUPFD_CLOEXEC, 0) == -1);
 260   ASSERT (errno == EBADF);
 261 
 262   
 263   errno = 0;
 264   ASSERT (fcntl (fd, F_DUPFD, -1) == -1);
 265   ASSERT (errno == EINVAL);
 266   errno = 0;
 267   ASSERT (fcntl (fd, F_DUPFD, bad_fd) == -1);
 268   ASSERT (errno == EINVAL);
 269   errno = 0;
 270   ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, -1) == -1);
 271   ASSERT (errno == EINVAL);
 272   errno = 0;
 273   ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, bad_fd) == -1);
 274   ASSERT (errno == EINVAL
 275           || errno == EMFILE );
 276 
 277   
 278 
 279   set_binary_mode (fd, O_BINARY);
 280   ASSERT (is_open (fd));
 281   ASSERT (!is_open (fd + 1));
 282   ASSERT (!is_open (fd + 2));
 283   ASSERT (is_inheritable (fd));
 284   ASSERT (is_mode (fd, O_BINARY));
 285 
 286   ASSERT (fcntl (fd, F_DUPFD, fd) == fd + 1);
 287   ASSERT (is_open (fd));
 288   ASSERT (is_open (fd + 1));
 289   ASSERT (!is_open (fd + 2));
 290   ASSERT (is_inheritable (fd + 1));
 291   ASSERT (is_mode (fd, O_BINARY));
 292   ASSERT (is_mode (fd + 1, O_BINARY));
 293   ASSERT (close (fd + 1) == 0);
 294 
 295   ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, fd + 2) == fd + 2);
 296   ASSERT (is_open (fd));
 297   ASSERT (!is_open (fd + 1));
 298   ASSERT (is_open (fd + 2));
 299   ASSERT (is_inheritable (fd));
 300   ASSERT (!is_inheritable (fd + 2));
 301   ASSERT (is_mode (fd, O_BINARY));
 302   ASSERT (is_mode (fd + 2, O_BINARY));
 303   ASSERT (close (fd) == 0);
 304 
 305   set_binary_mode (fd + 2, O_TEXT);
 306   ASSERT (fcntl (fd + 2, F_DUPFD, fd + 1) == fd + 1);
 307   ASSERT (!is_open (fd));
 308   ASSERT (is_open (fd + 1));
 309   ASSERT (is_open (fd + 2));
 310   ASSERT (is_inheritable (fd + 1));
 311   ASSERT (!is_inheritable (fd + 2));
 312   ASSERT (is_mode (fd + 1, O_TEXT));
 313   ASSERT (is_mode (fd + 2, O_TEXT));
 314   ASSERT (close (fd + 1) == 0);
 315 
 316   ASSERT (fcntl (fd + 2, F_DUPFD_CLOEXEC, 0) == fd);
 317   ASSERT (is_open (fd));
 318   ASSERT (!is_open (fd + 1));
 319   ASSERT (is_open (fd + 2));
 320   ASSERT (!is_inheritable (fd));
 321   ASSERT (!is_inheritable (fd + 2));
 322   ASSERT (is_mode (fd, O_TEXT));
 323   ASSERT (is_mode (fd + 2, O_TEXT));
 324   ASSERT (close (fd + 2) == 0);
 325 
 326   
 327   errno = 0;
 328   ASSERT (fcntl (-1, F_GETFD) == -1);
 329   ASSERT (errno == EBADF);
 330   errno = 0;
 331   ASSERT (fcntl (fd + 1, F_GETFD) == -1);
 332   ASSERT (errno == EBADF);
 333   errno = 0;
 334   ASSERT (fcntl (bad_fd, F_GETFD) == -1);
 335   ASSERT (errno == EBADF);
 336 
 337   
 338   {
 339     int result = fcntl (fd, F_GETFD);
 340     ASSERT (0 <= result);
 341     ASSERT ((result & FD_CLOEXEC) == FD_CLOEXEC);
 342     ASSERT (dup (fd) == fd + 1);
 343     result = fcntl (fd + 1, F_GETFD);
 344     ASSERT (0 <= result);
 345     ASSERT ((result & FD_CLOEXEC) == 0);
 346     ASSERT (close (fd + 1) == 0);
 347   }
 348 
 349 #ifdef F_SETFD
 350   
 351   errno = 0;
 352   ASSERT (fcntl (-1, F_SETFD, 0) == -1);
 353   ASSERT (errno == EBADF);
 354   errno = 0;
 355   ASSERT (fcntl (fd + 1, F_SETFD, 0) == -1);
 356   ASSERT (errno == EBADF);
 357   errno = 0;
 358   ASSERT (fcntl (bad_fd, F_SETFD, 0) == -1);
 359   ASSERT (errno == EBADF);
 360 #endif
 361 
 362 #ifdef F_GETFL
 363   
 364   errno = 0;
 365   ASSERT (fcntl (-1, F_GETFL) == -1);
 366   ASSERT (errno == EBADF);
 367   errno = 0;
 368   ASSERT (fcntl (fd + 1, F_GETFL) == -1);
 369   ASSERT (errno == EBADF);
 370   errno = 0;
 371   ASSERT (fcntl (bad_fd, F_GETFL) == -1);
 372   ASSERT (errno == EBADF);
 373 #endif
 374 
 375 #ifdef F_SETFL
 376   
 377   errno = 0;
 378   ASSERT (fcntl (-1, F_SETFL, 0) == -1);
 379   ASSERT (errno == EBADF);
 380   errno = 0;
 381   ASSERT (fcntl (fd + 1, F_SETFL, 0) == -1);
 382   ASSERT (errno == EBADF);
 383   errno = 0;
 384   ASSERT (fcntl (bad_fd, F_SETFL, 0) == -1);
 385   ASSERT (errno == EBADF);
 386 #endif
 387 
 388 #ifdef F_GETOWN
 389   
 390   errno = 0;
 391   ASSERT (fcntl (-1, F_GETOWN) == -1);
 392   ASSERT (errno == EBADF);
 393   errno = 0;
 394   ASSERT (fcntl (fd + 1, F_GETOWN) == -1);
 395   ASSERT (errno == EBADF);
 396   errno = 0;
 397   ASSERT (fcntl (bad_fd, F_GETOWN) == -1);
 398   ASSERT (errno == EBADF);
 399 #endif
 400 
 401 #ifdef F_SETOWN
 402   
 403   errno = 0;
 404   ASSERT (fcntl (-1, F_SETOWN, 0) == -1);
 405   ASSERT (errno == EBADF);
 406   errno = 0;
 407   ASSERT (fcntl (fd + 1, F_SETOWN, 0) == -1);
 408   ASSERT (errno == EBADF);
 409   errno = 0;
 410   ASSERT (fcntl (bad_fd, F_SETOWN, 0) == -1);
 411   ASSERT (errno == EBADF);
 412 #endif
 413 
 414   
 415   ASSERT (close (fd) == 0);
 416   ASSERT (unlink (file) == 0);
 417 
 418   
 419 
 420 
 421 
 422 
 423 
 424 
 425 
 426   (void) close (10);
 427 
 428   
 429   ASSERT (fcntl (1, F_DUPFD_CLOEXEC, 10) >= 0);
 430 #if defined _WIN32 && !defined __CYGWIN__
 431   return _execl ("./test-fcntl", "./test-fcntl", "child", NULL);
 432 #else
 433   return execl ("./test-fcntl", "./test-fcntl", "child", NULL);
 434 #endif
 435 }