aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--threadproc/unix/proc.c23
2 files changed, 24 insertions, 5 deletions
diff --git a/CHANGES b/CHANGES
index f479a7b78..4f5e476a1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,12 @@
Changes with APR b1
+ *) Fix some file cleanup problems in apr_proc_create() which could
+ result in the pipes for stdin/stdout/stderr being closed
+ immediately. [Jeff Trawick]
+
*) New functions apr_hash_[merge|copy], change to overlay fn
so that it calls merge, which does a inline iteration instead
- of calling the iterator function. [Brian Pan <bpane@pacbell.net]
+ of calling the iterator function. [Brian Pane <bpane@pacbell.net]
*) Introduce the apr_pool_userdata_setn() variant that doesn't
strdup the key. Allows both the _setn() and _set() variant to
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;
}