dup2, dup3: work around another cygwin crasher
[gnulib.git] / tests / test-dup3.c
index 41fc16d..5a4aa6d 100644 (file)
@@ -1,5 +1,5 @@
 /* Test duplicating file descriptors.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009-2013 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include <unistd.h>
 
+#include "signature.h"
+SIGNATURE_CHECK (dup3, int, (int, int, int));
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-/* Get declarations of the Win32 API functions.  */
+/* Get declarations of the native Windows API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "binary-io.h"
-
-#define ASSERT(expr) \
-  do                                                                         \
-    {                                                                        \
-      if (!(expr))                                                           \
-        {                                                                    \
-          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
-          fflush (stderr);                                                   \
-          abort ();                                                          \
-        }                                                                    \
-    }                                                                        \
-  while (0)
+#include "macros.h"
 
 /* Return true if FD is open.  */
 static bool
 is_open (int fd)
 {
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* On Win32, the initial state of unassigned standard file
+  /* On native Windows, the initial state of unassigned standard file
      descriptors is that they are open but point to an
      INVALID_HANDLE_VALUE, and there is no fcntl.  */
   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
@@ -84,8 +76,9 @@ int
 main ()
 {
   int use_cloexec;
+  int bad_fd = getdtablesize ();
 
-#if defined O_CLOEXEC
+#if O_CLOEXEC
   for (use_cloexec = 0; use_cloexec <= 1; use_cloexec++)
 #else
   use_cloexec = 0;
@@ -97,7 +90,7 @@ main ()
       char buffer[1];
 
       o_flags = 0;
-#if defined O_CLOEXEC
+#if O_CLOEXEC
       if (use_cloexec)
         o_flags |= O_CLOEXEC;
 #endif
@@ -131,8 +124,17 @@ main ()
       errno = 0;
       ASSERT (dup3 (fd, -2, o_flags) == -1);
       ASSERT (errno == EBADF);
+      if (bad_fd > 256)
+        {
+          ASSERT (dup3 (fd, 255, 0) == 255);
+          ASSERT (dup3 (fd, 256, 0) == 256);
+          ASSERT (close (255) == 0);
+          ASSERT (close (256) == 0);
+        }
+      ASSERT (dup3 (fd, bad_fd - 1, 0) == bad_fd - 1);
+      ASSERT (close (bad_fd - 1) == 0);
       errno = 0;
-      ASSERT (dup3 (fd, 10000000, o_flags) == -1);
+      ASSERT (dup3 (fd, bad_fd, o_flags) == -1);
       ASSERT (errno == EBADF);
 
       /* Using dup3 can skip fds.  */