From 6ed67a15a265e213d2cbaac25ccc995fddf73ac6 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 5 Dec 2009 06:39:09 -0700 Subject: [PATCH] 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 --- ChangeLog | 8 ++++++++ lib/pipe-safer.c | 50 +++++++++++++++++++++++++++++++++++++++----------- lib/pipe.c | 8 ++------ lib/unistd--.h | 7 ++++++- lib/unistd-safer.h | 4 ++++ modules/pipe | 1 + modules/pipe2-safer | 24 ++++++++++++++++++++++++ 7 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 modules/pipe2-safer diff --git a/ChangeLog b/ChangeLog index 21c86be91..90d6eb03c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2009-12-05 Eric Blake + 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 0fc685054..fda5c5287 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 d17c9bf6c..c3db1b586 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 1a7fd785b..6f1ebaf95 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 af7d4ea6b..70cc6998a 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 1d68eeb37..922bda16c 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 000000000..eb59487af --- /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 -- 2.11.0