diff options
author | Bojan Smojver <bojan@apache.org> | 2009-06-12 03:21:22 +0000 |
---|---|---|
committer | Bojan Smojver <bojan@apache.org> | 2009-06-12 03:21:22 +0000 |
commit | d8c00503725305c6f41f6efd58c1a3dcc06d1fcd (patch) | |
tree | 77bb8b73a8798597440f7cb9bfc72c247fa9971f /file_io/unix | |
parent | ad67ed01e13eadec2f9531ec71dca8bf0ca82b9f (diff) | |
download | apr-d8c00503725305c6f41f6efd58c1a3dcc06d1fcd.tar.gz |
Backport r747990, r748361, r748371, r748565, r748988, r749810, r783958
from the trunk.
Set CLOEXEC flags where appropriate. Either use new O_CLOEXEC flag and
associated functions, such as dup3(), accept4(), epoll_create1() etc., or
simply set CLOEXEC flag using fcntl().
Patch by Stefan Fritsch <sf sfritsch.de> and
Arkadiusz Miskiewicz <arekm pld-linux.org>.
PR 46425.
fix unused variable warning for builds without HAVE_DUP3
Unroll APR_SET_FD_CLOEXEC macro.
* One missing unroll of APR_SET_FD_CLOEXEC.
Document CLOEXEC patch.
Only set CLOEXEC on dup() if both NOCLEANUP and INHERIT flags are clear.
Retain the INHERIT/NOCLEANUP flags of new_file in apr_file_dup2().
Patch by Stefan Fritsch <sf sfritsch.de>.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@783970 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'file_io/unix')
-rw-r--r-- | file_io/unix/filedup.c | 25 | ||||
-rw-r--r-- | file_io/unix/mktemp.c | 10 | ||||
-rw-r--r-- | file_io/unix/open.c | 29 |
3 files changed, 62 insertions, 2 deletions
diff --git a/file_io/unix/filedup.c b/file_io/unix/filedup.c index adecbb7f0..47ea4f33b 100644 --- a/file_io/unix/filedup.c +++ b/file_io/unix/filedup.c @@ -25,13 +25,36 @@ static apr_status_t file_dup(apr_file_t **new_file, int which_dup) { int rv; - +#ifdef HAVE_DUP3 + int flags = 0; +#endif + if (which_dup == 2) { if ((*new_file) == NULL) { /* We can't dup2 unless we have a valid new_file */ return APR_EINVAL; } +#ifdef HAVE_DUP3 + if (!((*new_file)->flags & (APR_FILE_NOCLEANUP|APR_INHERIT))) + flags |= O_CLOEXEC; + rv = dup3(old_file->filedes, (*new_file)->filedes, flags); +#else rv = dup2(old_file->filedes, (*new_file)->filedes); + if (!((*new_file)->flags & (APR_FILE_NOCLEANUP|APR_INHERIT))) { + int flags; + + if (rv == -1) + return errno; + + if ((flags = fcntl((*new_file)->filedes, F_GETFD)) == -1) + return errno; + + flags |= FD_CLOEXEC; + if (fcntl((*new_file)->filedes, F_SETFD, flags) == -1) + return errno; + + } +#endif } else { rv = dup(old_file->filedes); } diff --git a/file_io/unix/mktemp.c b/file_io/unix/mktemp.c index 22e0bd5d3..a78b73ae9 100644 --- a/file_io/unix/mktemp.c +++ b/file_io/unix/mktemp.c @@ -51,6 +51,7 @@ #include "apr_strings.h" /* prototype of apr_mkstemp() */ #include "apr_arch_file_io.h" /* prototype of apr_mkstemp() */ #include "apr_portable.h" /* for apr_os_file_put() */ +#include "apr_arch_inherit.h" #ifndef HAVE_MKSTEMP @@ -203,6 +204,15 @@ APR_DECLARE(apr_status_t) apr_file_mktemp(apr_file_t **fp, char *template, apr_i (*fp)->fname = apr_pstrdup(p, template); if (!(flags & APR_FILE_NOCLEANUP)) { + int flags; + + if ((flags = fcntl(fd, F_GETFD)) == -1) + return errno; + + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + return errno; + apr_pool_cleanup_register((*fp)->pool, (void *)(*fp), apr_unix_file_cleanup, apr_unix_child_file_cleanup); diff --git a/file_io/unix/open.c b/file_io/unix/open.c index a4dce36ae..e10fc3dda 100644 --- a/file_io/unix/open.c +++ b/file_io/unix/open.c @@ -127,7 +127,15 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, oflags |= O_BINARY; } #endif - + +#ifdef O_CLOEXEC + /* Introduced in Linux 2.6.23. Silently ignored on earlier Linux kernels. + */ + if (!(flag & APR_FILE_NOCLEANUP)) { + oflags |= O_CLOEXEC; +} +#endif + #if APR_HAS_LARGE_FILES && defined(_LARGEFILE64_SOURCE) oflags |= O_LARGEFILE; #elif defined(O_LARGEFILE) @@ -155,6 +163,16 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, if (fd < 0) { return errno; } + if (!(flag & APR_FILE_NOCLEANUP)) { + int flags; + + if ((flags = fcntl(fd, F_GETFD)) == -1) + return errno; + + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + return errno; + } (*new) = (apr_file_t *)apr_pcalloc(pool, sizeof(apr_file_t)); (*new)->pool = pool; @@ -337,6 +355,15 @@ APR_DECLARE(apr_status_t) apr_file_inherit_unset(apr_file_t *thefile) return APR_EINVAL; } if (thefile->flags & APR_INHERIT) { + int flags; + + if ((flags = fcntl(thefile->filedes, F_GETFD)) == -1) + return errno; + + flags |= FD_CLOEXEC; + if (fcntl(thefile->filedes, F_SETFD, flags) == -1) + return errno; + thefile->flags &= ~APR_INHERIT; apr_pool_child_cleanup_set(thefile->pool, (void *)thefile, |