changeset 11870:ddd29d8cdded

New module 'pipe2'.
author Bruno Haible <bruno@clisp.org>
date Sat, 22 Aug 2009 18:46:44 +0200
parents fce330cf6651
children 35ea3cd86bec
files ChangeLog doc/glibc-functions/pipe2.texi lib/pipe2.c lib/unistd.in.h m4/pipe2.m4 m4/unistd_h.m4 modules/pipe2 modules/unistd
diffstat 8 files changed, 188 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-08-22  Bruno Haible  <bruno@clisp.org>
+
+	New module 'pipe2'.
+	* lib/unistd.in.h (pipe2): New declaration.
+	* lib/pipe2.c: New file.
+	* m4/pipe2.m4: New file.
+	* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_PIPE2 and
+	HAVE_PIPE2.
+	* modules/unistd (Makefile.am): Substitute GNULIB_PIPE2 and HAVE_PIPE2.
+	* modules/pipe2: New file.
+	* doc/glibc-functions/pipe2.texi: Mention the new module.
+
 2009-08-22  Bruno Haible  <bruno@clisp.org>
 
 	Reference some new glibc functions.
--- a/doc/glibc-functions/pipe2.texi
+++ b/doc/glibc-functions/pipe2.texi
@@ -2,15 +2,15 @@
 @subsection @code{pipe2}
 @findex pipe2
 
-Gnulib module: ---
+Gnulib module: pipe2
 
 Portability problems fixed by Gnulib:
 @itemize
-@end itemize
-
-Portability problems not fixed by Gnulib:
-@itemize
 @item
 This function is missing on all non-glibc platforms:
 MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5, BeOS.
 @end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end itemize
new file mode 100644
--- /dev/null
+++ b/lib/pipe2.c
@@ -0,0 +1,102 @@
+/* Create a pipe, with specific opening flags.
+   Copyright (C) 2009 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Native Woe32 API.  */
+
+# include <io.h>
+
+int
+pipe2 (int fd[2], int flags)
+{
+  /* Check the supported flags.  */
+  if ((flags & ~(O_CLOEXEC | O_BINARY | O_TEXT)) != 0)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  return _pipe (fd, 4096, flags);
+}
+
+#else
+/* Unix API.  */
+
+# ifndef O_CLOEXEC
+#  define O_CLOEXEC 0
+# endif
+
+int
+pipe2 (int fd[2], int flags)
+{
+  /* Check the supported flags.  */
+  if ((flags & ~(O_CLOEXEC | O_NONBLOCK)) != 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].  */
+
+  if (flags & O_NONBLOCK)
+    {
+      int fcntl_flags;
+
+      if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0
+	  || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) < 0
+	  || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0
+	  || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) < 0)
+	goto fail;
+    }
+
+  if (flags & O_CLOEXEC)
+    {
+      int fcntl_flags;
+
+      if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0
+	  || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) < 0
+	  || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0
+	  || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) < 0)
+	goto fail;
+    }
+
+  return 0;
+
+ fail:
+  {
+    int saved_errno = errno;
+    close (fd[0]);
+    close (fd[1]);
+    errno = saved_errno;
+    return -1;
+  }
+}
+
+#endif
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -531,6 +531,25 @@
 #endif
 
 
+#if @GNULIB_PIPE2@
+/* Create a pipe, applying the given flags when opening the read-end of the
+   pipe and the write-end of the pipe.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   Store the read-end as fd[0] and the write-end as fd[1].
+   Return 0 upon success, or -1 with errno set upon failure.  */
+# if !@HAVE_PIPE2@
+extern int pipe2 (int fd[2], int flags);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef pipe2
+# define pipe2(f,o) \
+    (GL_LINK_WARNING ("pipe2 is unportable - " \
+                      "use gnulib module pipe2 for portability"), \
+     pipe2 (f, o))
+#endif
+
+
 #if @GNULIB_READLINK@
 /* Read the contents of the symbolic link FILE and place the first BUFSIZE
    bytes of it into BUF.  Return the number of bytes placed into BUF if
new file mode 100644
--- /dev/null
+++ b/m4/pipe2.m4
@@ -0,0 +1,19 @@
+# pipe2.m4 serial 1
+dnl Copyright (C) 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_PIPE2],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+
+  dnl Persuade glibc <unistd.h> to declare pipe2().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_FUNCS_ONCE([pipe2])
+  if test $ac_cv_func_pipe2 != yes; then
+    HAVE_PIPE2=0
+    AC_LIBOBJ([pipe2])
+  fi
+])
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 19
+# unistd_h.m4 serial 20
 dnl Copyright (C) 2006-2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -50,6 +50,7 @@
   GNULIB_LCHOWN=0;           AC_SUBST([GNULIB_LCHOWN])
   GNULIB_LINK=0;             AC_SUBST([GNULIB_LINK])
   GNULIB_LSEEK=0;            AC_SUBST([GNULIB_LSEEK])
+  GNULIB_PIPE2=0;            AC_SUBST([GNULIB_PIPE2])
   GNULIB_READLINK=0;         AC_SUBST([GNULIB_READLINK])
   GNULIB_SLEEP=0;            AC_SUBST([GNULIB_SLEEP])
   GNULIB_UNISTD_H_GETOPT=0;  AC_SUBST([GNULIB_UNISTD_H_GETOPT])
@@ -66,6 +67,7 @@
   HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])
   HAVE_GETUSERSHELL=1;    AC_SUBST([HAVE_GETUSERSHELL])
   HAVE_LINK=1;            AC_SUBST([HAVE_LINK])
+  HAVE_PIPE2=1;           AC_SUBST([HAVE_PIPE2])
   HAVE_READLINK=1;        AC_SUBST([HAVE_READLINK])
   HAVE_SLEEP=1;           AC_SUBST([HAVE_SLEEP])
   HAVE_DECL_ENVIRON=1;    AC_SUBST([HAVE_DECL_ENVIRON])
new file mode 100644
--- /dev/null
+++ b/modules/pipe2
@@ -0,0 +1,26 @@
+Description:
+pipe2() function: create a pipe, with specific opening flags.
+
+Files:
+lib/pipe2.c
+m4/pipe2.m4
+
+Depends-on:
+unistd
+fcntl
+binary-io
+
+configure.ac:
+gl_FUNC_PIPE2
+gl_UNISTD_MODULE_INDICATOR([pipe2])
+
+Makefile.am:
+
+Include:
+<unistd.h>
+
+License:
+GPL
+
+Maintainer:
+Bruno Haible, Eric Blake
--- a/modules/unistd
+++ b/modules/unistd
@@ -43,6 +43,7 @@
 	      -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \
 	      -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \
 	      -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \
+	      -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \
 	      -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \
 	      -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \
 	      -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \
@@ -58,6 +59,7 @@
 	      -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
 	      -e 's|@''HAVE_GETUSERSHELL''@|$(HAVE_GETUSERSHELL)|g' \
 	      -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
+	      -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \
 	      -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
 	      -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
 	      -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \