diff options
Diffstat (limited to 'server/mpm/winnt/mpm_winnt.c')
-rw-r--r-- | server/mpm/winnt/mpm_winnt.c | 85 |
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) { |