API_EXPORT(void) ap_close_piped_log (piped_log *pl) { ap_block_alarms (); piped_log_cleanup (pl); ap_kill_cleanup (pl->p, pl, piped_log_cleanup); ap_unblock_alarms (); }
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; }
void accept_mutex_off() { int err = 0; /* Have to block alarms here, or else we might have a double-unlock, which * is possible with pthread mutexes, since they are designed to be fast, * and hence not necessarily make checks for ownership or multiple unlocks. */ ap_block_alarms(); if ((err = pthread_mutex_unlock(accept_mutex))) { errno = err; perror("pthread_mutex_unlock"); clean_child_exit(APEXIT_CHILDFATAL); } have_accept_mutex = 0; ap_unblock_alarms(); if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { perror("sigprocmask(SIG_SETMASK)"); clean_child_exit(1); } }
void accept_mutex_on() { int err = 0; if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { perror("sigprocmask(SIG_BLOCK)"); clean_child_exit(APEXIT_CHILDFATAL); } /* We need to block alarms here, since if we get killed *right* after * locking the mutex, have_accept_mutex will not be set, and our * child cleanup will not work. */ ap_block_alarms(); if ((err = pthread_mutex_lock(accept_mutex))) { errno = err; perror("pthread_mutex_lock"); clean_child_exit(APEXIT_CHILDFATAL); } have_accept_mutex = 1; ap_unblock_alarms(); }
static int piped_log_spawn (piped_log *pl) { int pid; ap_block_alarms(); pid = fork(); if (pid == 0) { /* XXX: this needs porting to OS2 and WIN32 */ /* XXX: need to check what open fds the logger is actually passed, * XXX: and CGIs for that matter ... cleanup_for_exec *should* * XXX: close all the relevant stuff, but hey, it could be broken. */ RAISE_SIGSTOP(PIPED_LOG_SPAWN); /* we're now in the child */ close (STDIN_FILENO); dup2 (pl->fds[0], STDIN_FILENO); ap_cleanup_for_exec (); signal (SIGCHLD, SIG_DFL); /* for HPUX */ signal (SIGHUP, SIG_IGN); execl (SHELL_PATH, SHELL_PATH, "-c", pl->program, NULL); fprintf (stderr, "piped_log_spawn: unable to exec %s -c '%s': %s\n", SHELL_PATH, pl->program, strerror (errno)); exit (1); } if (pid == -1) { fprintf (stderr, "piped_log_spawn: unable to fork(): %s\n", strerror (errno)); ap_unblock_alarms (); return -1; } ap_unblock_alarms(); pl->pid = pid; ap_register_other_child (pid, piped_log_maintenance, pl, pl->fds[1]); return 0; }