diff options
Diffstat (limited to 'srclib/apr/file_io/unix/open.c')
-rw-r--r-- | srclib/apr/file_io/unix/open.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/srclib/apr/file_io/unix/open.c b/srclib/apr/file_io/unix/open.c index e8404504..26db75c4 100644 --- a/srclib/apr/file_io/unix/open.c +++ b/srclib/apr/file_io/unix/open.c @@ -26,13 +26,15 @@ #include "fsio.h" #endif -static apr_status_t file_cleanup(apr_file_t *file) +static apr_status_t file_cleanup(apr_file_t *file, int is_child) { apr_status_t rv = APR_SUCCESS; if (close(file->filedes) == 0) { file->filedes = -1; - if (file->flags & APR_DELONCLOSE) { + + /* Only the parent process should delete the file! */ + if (!is_child && (file->flags & APR_DELONCLOSE)) { unlink(file->fname); } #if APR_HAS_THREADS @@ -68,14 +70,14 @@ apr_status_t apr_unix_file_cleanup(void *thefile) flush_rv = apr_file_flush(file); } - rv = file_cleanup(file); + rv = file_cleanup(file, 0); return rv != APR_SUCCESS ? rv : flush_rv; } apr_status_t apr_unix_child_file_cleanup(void *thefile) { - return file_cleanup(thefile); + return file_cleanup(thefile, 1); } APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, @@ -125,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) @@ -153,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; @@ -335,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, |