summaryrefslogtreecommitdiff
path: root/server/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/log.c')
-rw-r--r--server/log.c39
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");