View | Details | Raw Unified | Return to bug 57742
Collapse All | Expand All

(-)a/server/log.c (-38 / +86 lines)
Lines 65-70 Link Here
65
#undef APLOG_MODULE_INDEX
65
#undef APLOG_MODULE_INDEX
66
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
66
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
67
67
68
static piped_log* ap_open_piped_log_helper(apr_pool_t *p,
69
                                           const char *program,
70
                                           apr_cmdtype_e cmdtype,
71
                                           int dummy_stderr);
72
68
typedef struct {
73
typedef struct {
69
    const char *t_name;
74
    const char *t_name;
70
    int t_val;
75
    int t_val;
Lines 127-132 struct piped_log { Link Here
127
    apr_proc_t *pid;
132
    apr_proc_t *pid;
128
    /** How to reinvoke program when it must be replaced */
133
    /** How to reinvoke program when it must be replaced */
129
    apr_cmdtype_e cmdtype;
134
    apr_cmdtype_e cmdtype;
135
    /** Whether or not we need to open a dummy stderr */
136
    int dummy_stderr;
130
#endif
137
#endif
131
};
138
};
132
139
Lines 300-308 static int open_error_log(server_rec *s, int is_main, apr_pool_t *p) Link Here
300
{
307
{
301
    const char *fname;
308
    const char *fname;
302
    int rc;
309
    int rc;
310
    piped_log *pl = NULL;
303
311
304
    if (*s->error_fname == '|') {
312
    if (*s->error_fname == '|') {
305
        apr_file_t *dummy = NULL;
306
        apr_cmdtype_e cmdtype = APR_PROGRAM_ENV;
313
        apr_cmdtype_e cmdtype = APR_PROGRAM_ENV;
307
        fname = s->error_fname + 1;
314
        fname = s->error_fname + 1;
308
315
Lines 322-336 static int open_error_log(server_rec *s, int is_main, apr_pool_t *p) Link Here
322
         * the new child must use a dummy stderr since the current
329
         * the new child must use a dummy stderr since the current
323
         * stderr might be a pipe to the old logger.  Otherwise, the
330
         * stderr might be a pipe to the old logger.  Otherwise, the
324
         * child inherits the parents stderr. */
331
         * child inherits the parents stderr. */
325
        rc = log_child(p, fname, &dummy, cmdtype, is_main);
332
        pl = ap_open_piped_log_helper(p, fname, cmdtype, is_main);
326
        if (rc != APR_SUCCESS) {
333
327
            ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, APLOGNO(00089)
334
        if (pl == NULL || pl->write_fd == NULL) {
335
            /* no return code from open_piped_log()... */
336
            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, APLOGNO(00089)
328
                         "Couldn't start ErrorLog process '%s'.",
337
                         "Couldn't start ErrorLog process '%s'.",
329
                         s->error_fname + 1);
338
                         s->error_fname + 1);
330
            return DONE;
339
            return DONE;
331
        }
340
        }
332
341
333
        s->error_log = dummy;
342
        s->error_log = pl->write_fd;
334
    }
343
    }
335
    else if (s->errorlog_provider) {
344
    else if (s->errorlog_provider) {
336
        s->errorlog_provider_handle = s->errorlog_provider->init(p, s);
345
        s->errorlog_provider_handle = s->errorlog_provider->init(p, s);
Lines 358-363 static int open_error_log(server_rec *s, int is_main, apr_pool_t *p) Link Here
358
        }
367
        }
359
    }
368
    }
360
369
370
    if (is_main && s->error_log) {
371
        apr_file_flush(s->error_log);
372
        rc = apr_file_dup2(stderr_log, s->error_log, p);
373
        if (rc != APR_SUCCESS) {
374
            ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s, APLOGNO(00092)
375
                         "unable to replace stderr with error_log");
376
            return DONE;
377
        }
378
        else {
379
            /* We are done with stderr_pool, close it, killing
380
             * the previous generation's stderr logger
381
             */
382
            if (stderr_pool)
383
                apr_pool_destroy(stderr_pool);
384
            stderr_pool = p;
385
            /*
386
             * Now that we have dup'ed s->error_log to stderr_log close it and
387
             * set s->error_log to stderr_log. This avoids this fd being
388
             * inherited by the next piped logger who would keep open the
389
             * writing end of the pipe that this one uses as stdin. This in
390
             * turn would prevent the piped logger from exiting.
391
             */
392
            apr_file_close(s->error_log);
393
            s->error_log = stderr_log;
394
395
            /* If we've opened a piped logger, the writing end of the pipe
396
             * used to be s->error_log, which has since been closed; correct
397
             * that so it can be re-opened if the maintenance function is
398
             * called */
399
            if (pl && pl->write_fd) {
400
                pl->write_fd = s->error_log;
401
            }
402
        }
403
    }
404
361
    return OK;
405
    return OK;
362
}
406
}
363
407
Lines 390-430 int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, Link Here
390
    apr_pool_create(&stderr_p, apr_pool_parent_get(p));
434
    apr_pool_create(&stderr_p, apr_pool_parent_get(p));
391
    apr_pool_tag(stderr_p, "stderr_pool");
435
    apr_pool_tag(stderr_p, "stderr_pool");
392
436
437
    /* Open main error log, re-assign it to stderr */
393
    if (open_error_log(s_main, 1, stderr_p) != OK) {
438
    if (open_error_log(s_main, 1, stderr_p) != OK) {
394
        return DONE;
439
        return DONE;
395
    }
440
    }
396
441
397
    replace_stderr = 1;
442
    replace_stderr = (s_main->error_log == NULL);
398
    if (s_main->error_log) {
399
        apr_status_t rv;
400
401
        /* Replace existing stderr with new log. */
402
        apr_file_flush(s_main->error_log);
403
        rv = apr_file_dup2(stderr_log, s_main->error_log, stderr_p);
404
        if (rv != APR_SUCCESS) {
405
            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s_main, APLOGNO(00092)
406
                         "unable to replace stderr with error_log");
407
        }
408
        else {
409
            /* We are done with stderr_pool, close it, killing
410
             * the previous generation's stderr logger
411
             */
412
            if (stderr_pool)
413
                apr_pool_destroy(stderr_pool);
414
            stderr_pool = stderr_p;
415
            replace_stderr = 0;
416
            /*
417
             * Now that we have dup'ed s_main->error_log to stderr_log
418
             * close it and set s_main->error_log to stderr_log. This avoids
419
             * this fd being inherited by the next piped logger who would
420
             * keep open the writing end of the pipe that this one uses
421
             * as stdin. This in turn would prevent the piped logger from
422
             * exiting.
423
             */
424
             apr_file_close(s_main->error_log);
425
             s_main->error_log = stderr_log;
426
        }
427
    }
428
    /* note that stderr may still need to be replaced with something
443
    /* note that stderr may still need to be replaced with something
429
     * because it points to the old error log, or back to the tty
444
     * because it points to the old error log, or back to the tty
430
     * of the submitter.
445
     * of the submitter.
Lines 1642-1647 static apr_status_t piped_log_spawn(piped_log *pl) Link Here
1642
{
1657
{
1643
    apr_procattr_t *procattr;
1658
    apr_procattr_t *procattr;
1644
    apr_proc_t *procnew = NULL;
1659
    apr_proc_t *procnew = NULL;
1660
    apr_file_t *errfile;
1645
    apr_status_t status;
1661
    apr_status_t status;
1646
1662
1647
    if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) ||
1663
    if (((status = apr_procattr_create(&procattr, pl->p)) != APR_SUCCESS) ||
Lines 1666-1671 static apr_status_t piped_log_spawn(piped_log *pl) Link Here
1666
1682
1667
        apr_tokenize_to_argv(pl->program, &args, pl->p);
1683
        apr_tokenize_to_argv(pl->program, &args, pl->p);
1668
        procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t));
1684
        procnew = apr_pcalloc(pl->p, sizeof(apr_proc_t));
1685
1686
        if (pl->dummy_stderr) {
1687
            if ((status = apr_file_open_stdout(&errfile, pl->p)) == APR_SUCCESS)
1688
                status = apr_procattr_child_err_set(procattr, errfile, NULL);
1689
        }
1690
1669
        status = apr_proc_create(procnew, args[0], (const char * const *) args,
1691
        status = apr_proc_create(procnew, args[0], (const char * const *) args,
1670
                                 NULL, procattr, pl->p);
1692
                                 NULL, procattr, pl->p);
1671
1693
Lines 1761-1767 static apr_status_t piped_log_cleanup(void *data) Link Here
1761
    if (pl->pid != NULL) {
1783
    if (pl->pid != NULL) {
1762
        apr_proc_kill(pl->pid, SIGTERM);
1784
        apr_proc_kill(pl->pid, SIGTERM);
1763
    }
1785
    }
1764
    return piped_log_cleanup_for_exec(data);
1786
1787
    apr_file_close(pl->read_fd);
1788
    /* Down in ap_open_logs, if we're opening the main (non vhost) error log,
1789
     * we redirect stderr to pl->write_fd, and close the old pl->write_fd.
1790
     * Then, we assign pl->write_fd to stderr so that we can re-open the piped
1791
     * logger program in piped_log_maintenance. That means if the main error
1792
     * log's piped log program goes down, pl->write_fd here could be stderr,
1793
     * which we emphatically should not close. */
1794
    if (pl->write_fd != stderr_log) {
1795
        apr_file_close(pl->write_fd);
1796
    }
1797
    return APR_SUCCESS;
1765
}
1798
}
1766
1799
1767
1800
Lines 1769-1774 AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, Link Here
1769
                                             const char *program,
1802
                                             const char *program,
1770
                                             apr_cmdtype_e cmdtype)
1803
                                             apr_cmdtype_e cmdtype)
1771
{
1804
{
1805
    return ap_open_piped_log_helper(p, program, cmdtype, 0);
1806
}
1807
1808
static piped_log* ap_open_piped_log_helper(apr_pool_t *p,
1809
                                           const char *program,
1810
                                           apr_cmdtype_e cmdtype,
1811
                                           int dummy_stderr) {
1772
    piped_log *pl;
1812
    piped_log *pl;
1773
1813
1774
    pl = apr_palloc(p, sizeof (*pl));
1814
    pl = apr_palloc(p, sizeof (*pl));
Lines 1776-1781 AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, Link Here
1776
    pl->program = apr_pstrdup(p, program);
1816
    pl->program = apr_pstrdup(p, program);
1777
    pl->pid = NULL;
1817
    pl->pid = NULL;
1778
    pl->cmdtype = cmdtype;
1818
    pl->cmdtype = cmdtype;
1819
    pl->dummy_stderr = dummy_stderr;
1779
    if (apr_file_pipe_create_ex(&pl->read_fd,
1820
    if (apr_file_pipe_create_ex(&pl->read_fd,
1780
                                &pl->write_fd,
1821
                                &pl->write_fd,
1781
                                APR_FULL_BLOCK, p) != APR_SUCCESS) {
1822
                                APR_FULL_BLOCK, p) != APR_SUCCESS) {
Lines 1806-1816 AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, Link Here
1806
                                             const char *program,
1847
                                             const char *program,
1807
                                             apr_cmdtype_e cmdtype)
1848
                                             apr_cmdtype_e cmdtype)
1808
{
1849
{
1850
    return ap_open_piped_log_helper(p, program, cmdtype, 0);
1851
}
1852
1853
static piped_log* ap_open_piped_log_helper(apr_pool_t *p,
1854
                                             const char *program,
1855
                                             apr_cmdtype_e cmdtype,
1856
                                             int dummy_stderr)
1809
    piped_log *pl;
1857
    piped_log *pl;
1810
    apr_file_t *dummy = NULL;
1858
    apr_file_t *dummy = NULL;
1811
    int rc;
1859
    int rc;
1812
1860
1813
    rc = log_child(p, program, &dummy, cmdtype, 0);
1861
    rc = log_child(p, program, &dummy, cmdtype, dummy_stderr);
1814
    if (rc != APR_SUCCESS) {
1862
    if (rc != APR_SUCCESS) {
1815
        ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, APLOGNO(00108)
1863
        ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, NULL, APLOGNO(00108)
1816
                     "Couldn't start piped log process '%s'.",
1864
                     "Couldn't start piped log process '%s'.",

Return to bug 57742