From: Eric Blake <ebb9@byu.net>
Date: Sat, 5 Dec 2009 13:39:09 +0000 (-0700)
Subject: pipe2-safer: new module
X-Git-Tag: v0.1~5093
X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=6ed67a15a265e213d2cbaac25ccc995fddf73ac6;p=gnulib.git

pipe2-safer: new module

pipe2 deserves a *_safer variant.  It also makes the code in
pipe.c look simpler.

* modules/pipe2-safer: New file.
* lib/unistd-safer.h (pipe2_safer): New prototype.
* lib/unistd--.h (pipe2): New wrapper.
* lib/pipe-safer.c (pipe2_safer): New function.
* modules/pipe (Depends-on): Add pipe2-safer.
* lib/pipe.c (create_pipe) [WIN32]: Let pipe2_safer do the work.

Signed-off-by: Eric Blake <ebb9@byu.net>
---

diff --git a/ChangeLog b/ChangeLog
index 21c86be91a..90d6eb03c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2009-12-05  Eric Blake  <ebb9@byu.net>
 
+	pipe2-safer: new module
+	* modules/pipe2-safer: New file.
+	* lib/unistd-safer.h (pipe2_safer): New prototype.
+	* lib/unistd--.h (pipe2): New wrapper.
+	* lib/pipe-safer.c (pipe2_safer): New function.
+	* modules/pipe (Depends-on): Add pipe2-safer.
+	* lib/pipe.c (create_pipe) [WIN32]: Let pipe2_safer do the work.
+
 	stdlib-safer: preserve cloexec flag for mkostemp[s]
 	* lib/mkstemp-safer.c (mkostemp_safer, mkostemps_safer): Use new
 	fd_safer_flag.
diff --git a/lib/pipe-safer.c b/lib/pipe-safer.c
index 0fc685054b..fda5c52875 100644
--- a/lib/pipe-safer.c
+++ b/lib/pipe-safer.c
@@ -1,5 +1,5 @@
 /* Invoke pipe, but avoid some glitches.
-   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 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
@@ -35,16 +35,16 @@ pipe_safer (int fd[2])
     {
       int i;
       for (i = 0; i < 2; i++)
-	{
-	  fd[i] = fd_safer (fd[i]);
-	  if (fd[i] < 0)
-	    {
-	      int e = errno;
-	      close (fd[1 - i]);
-	      errno = e;
-	      return -1;
-	    }
-	}
+        {
+          fd[i] = fd_safer (fd[i]);
+          if (fd[i] < 0)
+            {
+              int e = errno;
+              close (fd[1 - i]);
+              errno = e;
+              return -1;
+            }
+        }
 
       return 0;
     }
@@ -54,3 +54,31 @@ pipe_safer (int fd[2])
 
   return -1;
 }
+
+#if GNULIB_PIPE2_SAFER
+/* Like pipe2, but ensure that neither of the file descriptors is
+   STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO.  */
+
+int
+pipe2_safer (int fd[2], int flags)
+{
+  if (pipe2 (fd, flags) == 0)
+    {
+      int i;
+      for (i = 0; i < 2; i++)
+        {
+          fd[i] = fd_safer_flag (fd[i], flags);
+          if (fd[i] < 0)
+            {
+              int e = errno;
+              close (fd[1 - i]);
+              errno = e;
+              return -1;
+            }
+        }
+
+      return 0;
+    }
+  return -1;
+}
+#endif /* GNULIB_PIPE2 */
diff --git a/lib/pipe.c b/lib/pipe.c
index d17c9bf6c6..c3db1b5860 100644
--- a/lib/pipe.c
+++ b/lib/pipe.c
@@ -133,14 +133,10 @@ create_pipe (const char *progname,
   prog_argv = prepare_spawn (prog_argv);
 
   if (pipe_stdout)
-    if (pipe2 (ifd, O_BINARY | O_NOINHERIT) < 0
-	|| (ifd[0] = fd_safer_noinherit (ifd[0])) < 0
-	|| (ifd[1] = fd_safer_noinherit (ifd[1])) < 0)
+    if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
       error (EXIT_FAILURE, errno, _("cannot create pipe"));
   if (pipe_stdin)
-    if (pipe2 (ofd, O_BINARY | O_NOINHERIT) < 0
-	|| (ofd[0] = fd_safer_noinherit (ofd[0])) < 0
-	|| (ofd[1] = fd_safer_noinherit (ofd[1])) < 0)
+    if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
       error (EXIT_FAILURE, errno, _("cannot create pipe"));
 /* Data flow diagram:
  *
diff --git a/lib/unistd--.h b/lib/unistd--.h
index 1a7fd785b0..6f1ebaf953 100644
--- a/lib/unistd--.h
+++ b/lib/unistd--.h
@@ -1,6 +1,6 @@
 /* Like unistd.h, but redefine some names to avoid glitches.
 
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 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
@@ -25,3 +25,8 @@
 
 #undef pipe
 #define pipe pipe_safer
+
+#if GNULIB_PIPE2_SAFER
+# undef pipe2
+# define pipe2 pipe2_safer
+#endif
diff --git a/lib/unistd-safer.h b/lib/unistd-safer.h
index af7d4ea6b8..70cc6998a5 100644
--- a/lib/unistd-safer.h
+++ b/lib/unistd-safer.h
@@ -25,3 +25,7 @@ int pipe_safer (int[2]);
 int dup_safer_flag (int, int);
 int fd_safer_flag (int, int);
 #endif
+
+#if GNULIB_PIPE2_SAFER
+int pipe2_safer (int[2], int);
+#endif
diff --git a/modules/pipe b/modules/pipe
index 1d68eeb37e..922bda16c6 100644
--- a/modules/pipe
+++ b/modules/pipe
@@ -17,6 +17,7 @@ fatal-signal
 gettext-h
 open
 pipe2
+pipe2-safer
 spawn
 posix_spawnp
 posix_spawn_file_actions_init
diff --git a/modules/pipe2-safer b/modules/pipe2-safer
new file mode 100644
index 0000000000..eb59487af0
--- /dev/null
+++ b/modules/pipe2-safer
@@ -0,0 +1,24 @@
+Description:
+pipe2_safer() function: create a pipe, with specific opening flags,
+without clobbering std{in,out,err}.
+
+Files:
+
+Depends-on:
+cloexec
+pipe2
+unistd-safer
+
+configure.ac:
+gl_MODULE_INDICATOR([pipe2-safer])
+
+Makefile.am:
+
+Include:
+"unistd-safer.h"
+
+License:
+GPL
+
+Maintainer:
+Eric Blake