/* Create a pipe, with specific opening flags.
- Copyright (C) 2009 Free Software Foundation, Inc.
+ Copyright (C) 2009-2011 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 <fcntl.h>
#include "binary-io.h"
+#include "verify.h"
+
+#if GNULIB_defined_O_NONBLOCK
+# include "nonblocking.h"
+#endif
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* Native Woe32 API. */
# include <io.h>
-#else
-/* Unix API. */
-
-# ifndef O_CLOEXEC
-# define O_CLOEXEC 0
-# endif
-
#endif
int
}
#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;
}
- return _pipe (fd, 4096, flags);
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Native Woe32 API. */
-#else
-/* Unix API. */
+ if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0)
+ return -1;
- /* Check the supported flags. */
- if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_TEXT | O_BINARY)) != 0)
+ /* O_NONBLOCK handling.
+ On native Windows platforms, O_NONBLOCK is defined by gnulib. Use the
+ functions defined by the gnulib module 'nonblocking'. */
+# if GNULIB_defined_O_NONBLOCK
+ if (flags & O_NONBLOCK)
{
- errno = EINVAL;
- return -1;
+ if (set_nonblocking_flag (fd[0], true) != 0
+ || set_nonblocking_flag (fd[1], true) != 0)
+ goto fail;
}
+# else
+ verify (O_NONBLOCK == 0);
+# endif
+
+ return 0;
+
+#else
+/* Unix API. */
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]. */
+ /* O_NONBLOCK handling.
+ On Unix platforms, O_NONBLOCK is defined by the system. Use fcntl(). */
if (flags & O_NONBLOCK)
{
int fcntl_flags;
return 0;
+#endif
+
fail:
{
int saved_errno = errno;
errno = saved_errno;
return -1;
}
-
-#endif
}