diff options
Diffstat (limited to 'threadproc/unix/proc.c')
-rw-r--r-- | threadproc/unix/proc.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/threadproc/unix/proc.c b/threadproc/unix/proc.c index 81a80b871..0ee409bbf 100644 --- a/threadproc/unix/proc.c +++ b/threadproc/unix/proc.c @@ -290,8 +290,7 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname, int status; /* child process */ - /* XXX major SNAFU - * + /* * If we do exec cleanup before the dup2() calls to set up pipes * on 0-2, we accidentally close the pipes used by programs like * mod_cgid. @@ -299,9 +298,27 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname, * If we do exec cleanup after the dup2() calls, cleanup can accidentally * close our pipes which replaced any files which previously had * descriptors 0-2. + * + * The solution is to kill the cleanup for the pipes, then do + * exec cleanup, then do the dup2() calls. */ if (attr->child_in) { + apr_pool_cleanup_kill(apr_file_pool_get(attr->child_in), + attr->child_in, apr_unix_file_cleanup); + } + if (attr->child_out) { + apr_pool_cleanup_kill(apr_file_pool_get(attr->child_out), + attr->child_out, apr_unix_file_cleanup); + } + if (attr->child_err) { + apr_pool_cleanup_kill(apr_file_pool_get(attr->child_err), + attr->child_err, apr_unix_file_cleanup); + } + + apr_pool_cleanup_for_exec(); + + if (attr->child_in) { apr_file_close(attr->parent_in); dup2(attr->child_in->filedes, STDIN_FILENO); apr_file_close(attr->child_in); @@ -325,8 +342,6 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname, } } - apr_pool_cleanup_for_exec(); - if ((status = limit_proc(attr)) != APR_SUCCESS) { return status; } |