From e038616f4a681bef050a2b20971c1d9af4fe7312 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 27 Jul 2008 19:08:19 +0000 Subject: * posix/wordexp.c (exec_comm): Use pipe2 if possible to create file descriptors with close-on-exec set. (exec_comm_child): Fix the case where the write end of the pipe is STDOUT_FILENO already. In case it is, clear close-on-exec. --- posix/wordexp.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 12 deletions(-) (limited to 'posix') diff --git a/posix/wordexp.c b/posix/wordexp.c index 765d14d..058a7cf 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -1,5 +1,5 @@ /* POSIX.2 wordexp implementation. - Copyright (C) 1997-2002, 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1997-2003, 2005, 2006, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Tim Waugh . @@ -42,6 +42,7 @@ # include #endif #include +#include #include #include @@ -824,17 +825,30 @@ exec_comm_child (char *comm, int *fildes, int showerr, int noexec) args[1] = "-nc"; /* Redirect output. */ - __dup2 (fildes[1], STDOUT_FILENO); - __close (fildes[1]); + if (__builtin_expect (fildes[1] != STDOUT_FILENO, 1)) + { + __dup2 (fildes[1], STDOUT_FILENO); + __close (fildes[1]); + } + else + { +#ifdef O_CLOEXEC + /* Reset the close-on-exec flag (if necessary). */ +# ifndef __ASSUME_PIPE2 + if (__have_pipe2 > 0) +# endif + __fcntl (fildes[1], F_SETFD, 0); +#endif + } /* Redirect stderr to /dev/null if we have to. */ if (showerr == 0) { struct stat64 st; int fd; - __close (2); + __close (STDERR_FILENO); fd = __open (_PATH_DEVNULL, O_WRONLY); - if (fd >= 0 && fd != 2) + if (fd >= 0 && fd != STDERR_FILENO) { __dup2 (fd, STDERR_FILENO); __close (fd); @@ -885,18 +899,38 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length, if (!comm || !*comm) return 0; - if (__pipe (fildes)) - /* Bad */ - return WRDE_NOSPACE; +#ifdef O_CLOEXEC +# ifndef __ASSUME_PIPE2 + if (__have_pipe2 >= 0) +# endif + { + int r = __pipe2 (fildes, O_CLOEXEC); +# ifndef __ASSUME_PIPE2 + if (__have_pipe2 == 0) + __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1; + + if (__have_pipe2 > 0) +# endif + if (r < 0) + /* Bad */ + return WRDE_NOSPACE; + } +#endif +#ifndef __ASSUME_PIPE2 +# ifdef O_CLOEXEC + if (__have_pipe2 < 0) +# endif + if (__pipe (fildes) < 0) + /* Bad */ + return WRDE_NOSPACE; +#endif again: if ((pid = __fork ()) < 0) { /* Bad */ - if (fildes[0] != -1) - __close (fildes[0]); - if (fildes[1] != -1) - __close (fildes[1]); + __close (fildes[0]); + __close (fildes[1]); return WRDE_NOSPACE; } -- cgit v1.1