From e038616f4a681bef050a2b20971c1d9af4fe7312 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 27 Jul 2008 19:08:19 +0000 Subject: [PATCH] * 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. --- ChangeLog | 6 +++++- NEWS | 12 ++++++++++-- libio/iopopen.c | 1 + posix/wordexp.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------------ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87baa5a..12d98d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2008-07-27 Ulrich Drepper + * 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. + * sysdeps/unix/sysv/linux/syscalls.list: Add __pipe2 alias. * io/pipe2.c: Likewise. * sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_PIPE2 @@ -9,7 +14,6 @@ * libio/Makefile (tests): Add tst-popen1. * libio/tst-popen1.c: New file. - * sysdeps/unix/sysv/linux/bits/socket.h: Define PF_ISDN and AF_ISDN. * sysdeps/unix/sysv/linux/sparc/bits/socket.h: Likewise. diff --git a/NEWS b/NEWS index eebc6b8..9873dde 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2008-5-14 +GNU C Library NEWS -- history of user-visible changes. 2008-7-27 Copyright (C) 1992-2007, 2008 Free Software Foundation, Inc. See the end for copying conditions. @@ -22,10 +22,18 @@ Version 2.9 * New implementation of memmem, strstr, and strcasestr which is O(n). Implemented by Eric Blake. + +* New Linux interfaces: inotify_init1, paccept, dup3, epoll_create2, pipe2 + +* Implement "e" option for popen to open file descriptor with the + close-on-exec flag set + +* Many functions, exported and internal, now atomically set the close-on-exec + flag when run on a sufficiently new kernel. Implemented by Ulrich Drepper. Version 2.8 -* New locales: bo_CN, bo_IN. +* New locales: bo_CN, bo_IN, shs_CA. * New encoding: HP-ROMAN9, HP-GREEK8, HP-THAI8, HP-TURKISH8. diff --git a/libio/iopopen.c b/libio/iopopen.c index 0ea7c23..09f3ba3 100644 --- a/libio/iopopen.c +++ b/libio/iopopen.c @@ -44,6 +44,7 @@ #endif #include #include +#include #ifndef _IO_fork #ifdef _LIBC 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; } -- 2.7.4