diff options
Diffstat (limited to 'server/log.c')
-rw-r--r-- | server/log.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/server/log.c b/server/log.c index 057672f2..c027f002 100644 --- a/server/log.c +++ b/server/log.c @@ -225,8 +225,13 @@ static void log_child_errfn(apr_pool_t *pool, apr_status_t err, "%s", description); } +/* Create a child process running PROGNAME with a pipe connected to + * the childs stdin. The write-end of the pipe will be placed in + * *FPIN on successful return. If dummy_stderr is non-zero, the + * stderr for the child will be the same as the stdout of the parent. + * Otherwise the child will inherit the stderr from the parent. */ static int log_child(apr_pool_t *p, const char *progname, - apr_file_t **fpin) + apr_file_t **fpin, int dummy_stderr) { /* Child process code for 'ErrorLog "|..."'; * may want a common framework for this, since I expect it will @@ -235,6 +240,7 @@ static int log_child(apr_pool_t *p, const char *progname, apr_status_t rc; apr_procattr_t *procattr; apr_proc_t *procnew; + apr_file_t *errfile; if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) && ((rc = apr_procattr_cmdtype_set(procattr, @@ -244,7 +250,12 @@ static int log_child(apr_pool_t *p, const char *progname, APR_NO_PIPE, APR_NO_PIPE)) == APR_SUCCESS) && ((rc = apr_procattr_error_check_set(procattr, 1)) == APR_SUCCESS) - && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) == APR_SUCCESS)) { + && ((rc = apr_procattr_child_errfn_set(procattr, log_child_errfn)) == APR_SUCCESS) + && (!dummy_stderr + || ((rc = apr_file_open_stdout(&errfile, p)) == APR_SUCCESS + && (rc = apr_procattr_child_err_set(procattr, + errfile, + errfile)) == APR_SUCCESS))) { char **args; const char *pname; @@ -261,12 +272,21 @@ static int log_child(apr_pool_t *p, const char *progname, * close_handle_in_child() */ } + + /* apr_procattr_child_err_set dups errfile twice: close the + * remaining "parent-side" copy (apr_proc_create closes the + * other). */ + if (dummy_stderr) { + apr_file_close(procnew->err); + } } return rc; } -static int open_error_log(server_rec *s, apr_pool_t *p) +/* Open the error log for the given server_rec. If IS_MAIN is + * non-zero, s is the main server. */ +static int open_error_log(server_rec *s, int is_main, apr_pool_t *p) { const char *fname; int rc; @@ -274,8 +294,11 @@ static int open_error_log(server_rec *s, apr_pool_t *p) if (*s->error_fname == '|') { apr_file_t *dummy = NULL; - /* This starts a new process... */ - rc = log_child (p, s->error_fname + 1, &dummy); + /* Spawn a new child logger. If this is the main server_rec, + * the new child must use a dummy stderr since the current + * stderr might be a pipe to the old logger. Otherwise, the + * child inherits the parents stderr. */ + rc = log_child(p, s->error_fname + 1, &dummy, is_main); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start ErrorLog process"); @@ -338,7 +361,7 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, apr_pool_cleanup_register(p, NULL, clear_handle_list, apr_pool_cleanup_null); - if (open_error_log(s_main, p) != OK) { + if (open_error_log(s_main, 1, p) != OK) { return DONE; } @@ -377,7 +400,7 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, } if (q == virt) { - if (open_error_log(virt, p) != OK) { + if (open_error_log(virt, 0, p) != OK) { return DONE; } } @@ -955,7 +978,7 @@ AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program) apr_file_t *dummy = NULL; int rc; - rc = log_child(p, program, &dummy); + rc = log_child(p, program, &dummy, 0); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, "Couldn't start piped log process"); |