diff -urN apr-1.3.3.org/file_io/unix/filedup.c apr-1.3.3/file_io/unix/filedup.c --- apr-1.3.3.org/file_io/unix/filedup.c 2007-05-15 04:37:16.000000000 +0200 +++ apr-1.3.3/file_io/unix/filedup.c 2009-02-23 08:15:10.023641368 +0100 @@ -24,7 +24,7 @@ apr_file_t *old_file, apr_pool_t *p, int which_dup) { - int rv; + int rv, fdflags; if (which_dup == 2) { if ((*new_file) == NULL) { @@ -32,6 +32,14 @@ return APR_EINVAL; } rv = dup2(old_file->filedes, (*new_file)->filedes); + if (!(old_file->flags & APR_INHERIT)) { + fdflags = fcntl((*new_file)->filedes, F_GETFD); + if (fdflags == -1) + return errno; + fdflags |= FD_CLOEXEC; + if (fcntl((*new_file)->filedes, F_SETFD, fdflags) == -1) + return errno; + } } else { rv = dup(old_file->filedes); } diff -urN apr-1.3.3.org/file_io/unix/mktemp.c apr-1.3.3/file_io/unix/mktemp.c --- apr-1.3.3.org/file_io/unix/mktemp.c 2007-06-01 19:58:04.000000000 +0200 +++ apr-1.3.3/file_io/unix/mktemp.c 2009-02-23 08:18:30.420011379 +0100 @@ -203,6 +203,11 @@ (*fp)->fname = apr_pstrdup(p, template); if (!(flags & APR_FILE_NOCLEANUP)) { + int fdflags = fcntl(fd, F_GETFD); + if (fdflags != -1) { + fdflags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, fdflags); + } apr_pool_cleanup_register((*fp)->pool, (void *)(*fp), apr_unix_file_cleanup, apr_unix_child_file_cleanup); diff -urN apr-1.3.3.org/file_io/unix/open.c apr-1.3.3/file_io/unix/open.c --- apr-1.3.3.org/file_io/unix/open.c 2007-05-15 04:37:16.000000000 +0200 +++ apr-1.3.3/file_io/unix/open.c 2009-02-23 08:13:44.356609676 +0100 @@ -125,7 +125,15 @@ 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) @@ -153,6 +161,11 @@ if (fd < 0) { return errno; } + if (!(flag & APR_FILE_NOCLEANUP)) { + int fdflags = fcntl(fd, F_GETFD); + fdflags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, fdflags); + } (*new) = (apr_file_t *)apr_pcalloc(pool, sizeof(apr_file_t)); (*new)->pool = pool; diff -urN apr-1.3.3.org/include/arch/unix/apr_arch_inherit.h apr-1.3.3/include/arch/unix/apr_arch_inherit.h --- apr-1.3.3.org/include/arch/unix/apr_arch_inherit.h 2006-08-03 12:55:31.000000000 +0200 +++ apr-1.3.3/include/arch/unix/apr_arch_inherit.h 2009-02-23 08:17:48.033064583 +0100 @@ -27,6 +27,12 @@ if (the##name->flag & APR_FILE_NOCLEANUP) \ return APR_EINVAL; \ if (!(the##name->flag & APR_INHERIT)) { \ + int fdflags = fcntl(the##name->name##des, F_GETFD); \ + if (fdflags == -1) \ + return errno; \ + fdflags &= ~(FD_CLOEXEC); \ + if (fcntl(the##name->name##des, F_SETFD, fdflags) == -1) \ + return errno; \ the##name->flag |= APR_INHERIT; \ apr_pool_child_cleanup_set(the##name->pool, \ (void *)the##name, \ @@ -41,6 +47,12 @@ if (the##name->flag & APR_FILE_NOCLEANUP) \ return APR_EINVAL; \ if (the##name->flag & APR_INHERIT) { \ + int fdflags = fcntl(the##name->name##des, F_GETFD); \ + if (fdflags == -1) \ + return errno; \ + fdflags |= FD_CLOEXEC; \ + if (fcntl(the##name->name##des, F_SETFD, fdflags) == -1) \ + return errno; \ the##name->flag &= ~APR_INHERIT; \ apr_pool_child_cleanup_set(the##name->pool, \ (void *)the##name, \ diff -urN apr-1.3.3.org/network_io/unix/sockets.c apr-1.3.3/network_io/unix/sockets.c --- apr-1.3.3.org/network_io/unix/sockets.c 2009-02-23 08:08:40.966440943 +0100 +++ apr-1.3.3/network_io/unix/sockets.c 2009-02-23 08:19:02.086419869 +0100 @@ -83,7 +83,7 @@ apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type, int protocol, apr_pool_t *cont) { - int family = ofamily; + int family = ofamily, fdflags; if (family == APR_UNSPEC) { #if APR_HAVE_IPV6 @@ -130,6 +130,13 @@ } set_socket_vars(*new, family, type, protocol); + fdflags = fcntl((*new)->socketdes, F_GETFD); + if (fdflags == -1) + return errno; + fdflags |= FD_CLOEXEC; + if (fcntl((*new)->socketdes, F_SETFD, fdflags) == -1) + return errno; + (*new)->timeout = -1; (*new)->inherit = 0; apr_pool_cleanup_register((*new)->pool, (void *)(*new), socket_cleanup, @@ -183,7 +183,7 @@ apr_status_t apr_socket_accept(apr_socket_t **new, apr_socket_t *sock, apr_pool_t *connection_context) { - int s; + int s, fdflags; apr_sockaddr_t sa; sa.salen = sizeof(sa.sa); @@ -255,6 +262,13 @@ (*new)->local_interface_unknown = 1; } + fdflags = fcntl((*new)->socketdes, F_GETFD); + if (fdflags == -1) + return errno; + fdflags |= FD_CLOEXEC; + if (fcntl((*new)->socketdes, F_SETFD, fdflags) == -1) + return errno; + (*new)->inherit = 0; apr_pool_cleanup_register((*new)->pool, (void *)(*new), socket_cleanup, socket_cleanup); diff -urN apr-1.3.3.org/poll/unix/epoll.c apr-1.3.3/poll/unix/epoll.c --- apr-1.3.3.org/poll/unix/epoll.c 2008-04-13 13:37:52.000000000 +0200 +++ apr-1.3.3/poll/unix/epoll.c 2009-02-23 08:20:07.663209400 +0100 @@ -91,7 +91,7 @@ apr_uint32_t flags) { apr_status_t rv; - int fd; + int fd, fdflags; fd = epoll_create(size); if (fd < 0) { @@ -99,6 +99,12 @@ return errno; } + fdflags = fcntl(fd, F_GETFD); + if (fdflags != -1) { + fdflags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, fdflags); + } + *pollset = apr_palloc(p, sizeof(**pollset)); #if APR_HAS_THREADS if ((flags & APR_POLLSET_THREADSAFE) && @@ -315,14 +321,20 @@ apr_pool_t *p, apr_uint32_t flags) { - int fd; - + int fd, fdflags; + fd = epoll_create(size); if (fd < 0) { *pollcb = NULL; return apr_get_netos_error(); } + + fdflags = fcntl(fd, F_GETFD); + if (fdflags != -1) { + fdflags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, fdflags); + } *pollcb = apr_palloc(p, sizeof(**pollcb)); (*pollcb)->nalloc = size;