diff lib/pipe2.c @ 14535:7ba508565384

pipe2: fix O_NONBLOCK support on mingw * modules/pipe2 (Depends-on): Add nonblocking. * lib/pipe2.c (pipe2) [WIN32]: Add O_NONBLOCK support. * tests/test-pipe2.c (is_nonblocking): Adjust test accordingly. * tests/test-nonblocking.c (main): Likewise. * modules/pipe2-tests (Makefile.am): Avoid link failure. Signed-off-by: Eric Blake <eblake@redhat.com>
author Eric Blake <eblake@redhat.com>
date Fri, 08 Apr 2011 10:52:55 -0600 (2011-04-08)
parents 97fc9a21a8fb
children cc17a319ded6
line wrap: on
line diff
--- a/lib/pipe2.c
+++ b/lib/pipe2.c
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 
 #include "binary-io.h"
+#include "nonblocking.h"
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 /* Native Woe32 API.  */
@@ -55,34 +56,43 @@
   }
 #endif
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-/* Native Woe32 API.  */
-
   /* Check the supported flags.  */
-  if ((flags & ~(O_CLOEXEC | O_BINARY | O_TEXT)) != 0)
+  if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0)
     {
       errno = EINVAL;
       return -1;
     }
 
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Native Woe32 API.  */
+
+  if (flags & O_NONBLOCK)
+    {
+      int result = _pipe (fd, 4096, flags & ~O_NONBLOCK);
+      if (result != 0)
+        return result;
+      if (set_nonblocking_flag (fd[0], true) != 0
+          || set_nonblocking_flag (fd[1], true) != 0)
+        {
+          int saved_errno = errno;
+          close (fd[0]);
+          close (fd[1]);
+          result = -1;
+          errno = saved_errno;
+        }
+      return result;
+    }
   return _pipe (fd, 4096, flags);
 
 #else
 /* Unix API.  */
 
-  /* Check the supported flags.  */
-  if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_TEXT | O_BINARY)) != 0)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
   if (pipe (fd) < 0)
     return -1;
 
   /* POSIX <http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html>
      says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on
-     both fd[0] amd fd[1].  */
+     both fd[0] and fd[1].  */
 
   if (flags & O_NONBLOCK)
     {