summaryrefslogtreecommitdiff
path: root/server/mpm/winnt/mpm_winnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/mpm/winnt/mpm_winnt.c')
-rw-r--r--server/mpm/winnt/mpm_winnt.c85
1 files changed, 57 insertions, 28 deletions
diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c
index 4b37d741..120adfc0 100644
--- a/server/mpm/winnt/mpm_winnt.c
+++ b/server/mpm/winnt/mpm_winnt.c
@@ -625,6 +625,7 @@ static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_
apr_pool_t *ptemp;
apr_procattr_t *attr;
apr_proc_t new_child;
+ apr_file_t *child_out, *child_err;
HANDLE hExitEvent;
HANDLE waitlist[2]; /* see waitlist_e */
char *cmd;
@@ -678,6 +679,22 @@ static int create_process(apr_pool_t *p, HANDLE *child_proc, HANDLE *child_exit_
return -1;
}
+ /* httpd-2.0/2.2 specific to work around apr_proc_create bugs */
+ if (((rv = apr_file_open_stdout(&child_out, p))
+ != APR_SUCCESS) ||
+ ((rv = apr_procattr_child_out_set(attr, child_out, NULL))
+ != APR_SUCCESS)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
+ "Parent: Could not set child process stdout");
+ }
+ if (((rv = apr_file_open_stderr(&child_err, p))
+ != APR_SUCCESS) ||
+ ((rv = apr_procattr_child_err_set(attr, child_err, NULL))
+ != APR_SUCCESS)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf,
+ "Parent: Could not set child process stderr");
+ }
+
/* Create the child_ready_event */
waitlist[waitlist_ready] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!waitlist[waitlist_ready]) {
@@ -975,9 +992,11 @@ die_now:
event_handles[CHILD_HANDLE] = NULL;
}
}
+ CloseHandle(child_exit_event);
return 0; /* Tell the caller we do not want to restart */
}
winnt_mpm_state = AP_MPMQ_STARTING;
+ CloseHandle(child_exit_event);
return 1; /* Tell the caller we want a restart */
}
@@ -1081,7 +1100,7 @@ void winnt_rewrite_args(process_rec *process)
pid = getenv("AP_PARENT_PID");
if (pid)
{
- HANDLE filehand, newhand;
+ HANDLE filehand;
HANDLE hproc = GetCurrentProcess();
/* This is the child */
@@ -1094,17 +1113,12 @@ void winnt_rewrite_args(process_rec *process)
/* The parent gave us stdin, we need to remember this
* handle, and no longer inherit it at our children
* (we can't slurp it up now, we just aren't ready yet).
+ * The original handle is closed below, at apr_file_dup2()
*/
pipe = GetStdHandle(STD_INPUT_HANDLE);
-
- if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- /* This doesn't work for 9x, but it's cleaner. */
- SetHandleInformation(pipe, HANDLE_FLAG_INHERIT, 0);
- }
- else if (DuplicateHandle(hproc, pipe,
- hproc, &filehand, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- CloseHandle(pipe);
+ if (DuplicateHandle(hproc, pipe,
+ hproc, &filehand, 0, FALSE,
+ DUPLICATE_SAME_ACCESS)) {
pipe = filehand;
}
@@ -1114,13 +1128,17 @@ void winnt_rewrite_args(process_rec *process)
* Don't infect child processes with our stdin
* handle, use another handle to NUL!
*/
- if ((filehand = GetStdHandle(STD_OUTPUT_HANDLE))
- && DuplicateHandle(hproc, filehand,
- hproc, &newhand, 0,
- TRUE, DUPLICATE_SAME_ACCESS)) {
- SetStdHandle(STD_INPUT_HANDLE, newhand);
+ {
+ apr_file_t *infile, *outfile;
+ if ((apr_file_open_stdout(&outfile, process->pool) == APR_SUCCESS)
+ && (apr_file_open_stdin(&infile, process->pool) == APR_SUCCESS))
+ apr_file_dup2(infile, outfile, process->pool);
}
+ /* This child needs the existing stderr opened for logging,
+ * already
+ */
+
/* The parent is responsible for providing the
* COMPLETE ARGUMENTS REQUIRED to the child.
*
@@ -1286,19 +1304,10 @@ void winnt_rewrite_args(process_rec *process)
if ((rv = apr_file_open(&nullfile, "NUL",
APR_READ | APR_WRITE, APR_OS_DEFAULT,
process->pool)) == APR_SUCCESS) {
- HANDLE hproc = GetCurrentProcess();
- HANDLE nullstdout = NULL;
- HANDLE nullhandle;
-
- /* Duplicate the handle to be inherited by children */
- if ((apr_os_file_get(&nullhandle, nullfile) == APR_SUCCESS)
- && DuplicateHandle(hproc, nullhandle,
- hproc, &nullstdout,
- 0, TRUE, DUPLICATE_SAME_ACCESS)) {
- SetStdHandle(STD_OUTPUT_HANDLE, nullstdout);
- }
-
- /* Close the original handle, we used the duplicate */
+ apr_file_t *nullstdout;
+ if (apr_file_open_stdout(&nullstdout, process->pool)
+ == APR_SUCCESS)
+ apr_file_dup2(nullstdout, nullfile, process->pool);
apr_file_close(nullfile);
}
}
@@ -1426,6 +1435,26 @@ static int winnt_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *pt
service_name);
exit(APEXIT_INIT);
}
+ else if (!one_process && !ap_my_generation) {
+ /* Open a null handle to soak stdout in this process.
+ * We need to emulate apr_proc_detach, unix performs this
+ * same check in the pre_config hook (although it is
+ * arguably premature). Services already fixed this.
+ */
+ apr_file_t *nullfile;
+ apr_status_t rv;
+ apr_pool_t *pproc = apr_pool_parent_get(pconf);
+
+ if ((rv = apr_file_open(&nullfile, "NUL",
+ APR_READ | APR_WRITE, APR_OS_DEFAULT,
+ pproc)) == APR_SUCCESS) {
+ apr_file_t *nullstdout;
+ if (apr_file_open_stdout(&nullstdout, pproc)
+ == APR_SUCCESS)
+ apr_file_dup2(nullstdout, nullfile, pproc);
+ apr_file_close(nullfile);
+ }
+ }
/* Win9x: disable AcceptEx */
if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {