API_EXPORT(piped_log *) ap_open_piped_log (pool *p, const char *program) { piped_log *pl; pl = ap_palloc (p, sizeof (*pl)); pl->p = p; pl->program = ap_pstrdup (p, program); pl->pid = -1; ap_block_alarms (); if (pipe (pl->fds) == -1) { int save_errno = errno; ap_unblock_alarms(); errno = save_errno; return NULL; } ap_register_cleanup (p, pl, piped_log_cleanup, piped_log_cleanup_for_exec); if (piped_log_spawn (pl) == -1) { int save_errno = errno; ap_kill_cleanup (p, pl, piped_log_cleanup); close (pl->fds[0]); close (pl->fds[1]); ap_unblock_alarms (); errno = save_errno; return NULL; } ap_unblock_alarms (); return pl; }
AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p, const char *program, apr_cmdtype_e cmdtype) { piped_log *pl; pl = apr_palloc(p, sizeof (*pl)); pl->p = p; pl->program = apr_pstrdup(p, program); pl->pid = NULL; pl->cmdtype = cmdtype; if (apr_file_pipe_create(&ap_piped_log_read_fd(pl), &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) { return NULL; } apr_pool_cleanup_register(p, pl, piped_log_cleanup, piped_log_cleanup_for_exec); if (piped_log_spawn(pl) != APR_SUCCESS) { apr_pool_cleanup_kill(p, pl, piped_log_cleanup); apr_file_close(ap_piped_log_read_fd(pl)); apr_file_close(ap_piped_log_write_fd(pl)); return NULL; } return pl; }
static void piped_log_maintenance(int reason, void *data, apr_wait_t status) { piped_log *pl = data; apr_status_t stats; int mpm_state; switch (reason) { case APR_OC_REASON_DEATH: case APR_OC_REASON_LOST: pl->pid = NULL; /* in case we don't get it going again, this * tells other logic not to try to kill it */ apr_proc_other_child_unregister(pl); stats = ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state); if (stats != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "can't query MPM state; not restarting " "piped log program '%s'", pl->program); } else if (mpm_state != AP_MPMQ_STOPPING) { ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "piped log program '%s' failed unexpectedly", pl->program); if ((stats = piped_log_spawn(pl)) != APR_SUCCESS) { /* what can we do? This could be the error log we're having * problems opening up... */ char buf[120]; ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "piped_log_maintenance: unable to respawn '%s': %s", pl->program, apr_strerror(stats, buf, sizeof(buf))); } } break; case APR_OC_REASON_UNWRITABLE: /* We should not kill off the pipe here, since it may only be full. * If it really is locked, we should kill it off manually. */ break; case APR_OC_REASON_RESTART: if (pl->pid != NULL) { apr_proc_kill(pl->pid, SIGTERM); pl->pid = NULL; } break; case APR_OC_REASON_UNREGISTER: break; } }
static void piped_log_maintenance (int reason, void *data, int status) { piped_log *pl = data; switch (reason) { case OC_REASON_DEATH: case OC_REASON_LOST: pl->pid = -1; ap_unregister_other_child (pl); if (pl->program == NULL) { /* during a restart */ break; } if (piped_log_spawn (pl) == -1) { /* what can we do? This could be the error log we're having * problems opening up... */ fprintf (stderr, "piped_log_maintenance: unable to respawn '%s': %s\n", pl->program, strerror (errno)); } break; case OC_REASON_UNWRITABLE: if (pl->pid != -1) { kill (pl->pid, SIGTERM); } break; case OC_REASON_RESTART: pl->program = NULL; if (pl->pid != -1) { kill (pl->pid, SIGTERM); } break; case OC_REASON_UNREGISTER: break; } }