From 7988d7308a32406577a1aa05d1a3070b4c3630d4 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 22 Aug 2009 18:46:44 +0200 Subject: [PATCH] New module 'pipe2'. --- ChangeLog | 12 +++++ doc/glibc-functions/pipe2.texi | 8 ++-- lib/pipe2.c | 102 +++++++++++++++++++++++++++++++++++++++++ lib/unistd.in.h | 19 ++++++++ m4/pipe2.m4 | 19 ++++++++ m4/unistd_h.m4 | 4 +- modules/pipe2 | 26 +++++++++++ modules/unistd | 2 + 8 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 lib/pipe2.c create mode 100644 m4/pipe2.m4 create mode 100644 modules/pipe2 diff --git a/ChangeLog b/ChangeLog index a9df6451a..6fa47bb44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2009-08-22 Bruno Haible + 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 + Reference some new glibc functions. * doc/glibc-functions/accept4.texi: New file. * doc/glibc-functions/dup3.texi: New file. diff --git a/doc/glibc-functions/pipe2.texi b/doc/glibc-functions/pipe2.texi index 5df4f7bfe..989245cf4 100644 --- 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 +@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 -@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 diff --git a/lib/pipe2.c b/lib/pipe2.c new file mode 100644 index 000000000..68677deac --- /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 + +/* Specification. */ +#include + +#include +#include + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Native Woe32 API. */ + +# include + +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 + 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 diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 769617879..7dc33bc69 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -531,6 +531,25 @@ extern int link (const char *path1, const char *path2); #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 ) + 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 diff --git a/m4/pipe2.m4 b/m4/pipe2.m4 new file mode 100644 index 000000000..d0aae439e --- /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 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 +]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index d7a89e130..bff2f283d 100644 --- 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 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], 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 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], 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]) diff --git a/modules/pipe2 b/modules/pipe2 new file mode 100644 index 000000000..90a0d127e --- /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: + + +License: +GPL + +Maintainer: +Bruno Haible, Eric Blake diff --git a/modules/unistd b/modules/unistd index 0c6cd9cd0..7fed07d4a 100644 --- a/modules/unistd +++ b/modules/unistd @@ -43,6 +43,7 @@ unistd.h: unistd.in.h -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 @@ unistd.h: unistd.in.h -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' \ -- 2.11.0