static void reap_child(pid_t pid, int exit_status) { int n; fd_set fd0; struct timeval tv; FD_ZERO(&fd0); FD_SET(0, &fd0); tv.tv_sec=0; tv.tv_usec=0; if (select(1, &fd0, 0, 0, &tv) >= 0) { if (FD_ISSET(0, &fd0)) return; } n=wait_reforkchild(nchildren, children, pid); if (n < 0) { unsigned u; clog_open_syslog("perlfilter"); clog_msg_str("ERR: Unable to restart a child process" " - aborting."); clog_msg_send(); for (u=0; u<nchildren; u++) if (children[u] >= 0) kill(children[u], SIGKILL); exit(0); } if (n > 0) { wait_restore(); if (exit_status) { clog_open_syslog("perlfilter"); clog_msg_str("ERR: Child process "); clog_msg_uint(pid); clog_msg_str(" terminated - restarting."); clog_msg_send(); } perlfilter(); } }
static pid_t start_child() { pid_t p; wait_block(); while ((p=fork()) == (pid_t)-1) { perror("fork"); sleep(3); } ++started; if (p == 0) { wait_restore(); } else wait_clear(&sighandler); return (p); }
int main(int argc, char **argv, char **env) { char *fn, *f; int rc; char buffer[1]; int waitstat; struct stat stat_buf; fn=config_localfilename("filters/perlfilter-numprocs"); if ( (f=config_read1l(fn)) != 0) { sscanf(f, "%u", &nchildren); free(f); } free(fn); if (nchildren <= 0) nchildren=1; fn=config_localfilename("filters/perlfilter"); if ( (f=config_read1l(fn)) == 0) { fprintf(stderr, "filters/perlfilter: not defined.\n"); exit(1); } filter=f; if (stat(filter, &stat_buf)) { perror(filter); exit(1); } listen_sock=lf_init("filters/perlfilter-mode", ALLFILTERSOCKETDIR "/perlfilter", ALLFILTERSOCKETDIR "/.perlfilter", FILTERSOCKETDIR "/perlfilter", FILTERSOCKETDIR "/.perlfilter"); if (listen_sock < 0) { perror("socket"); exit(1); } rc=wait_startchildren(nchildren, &children); if (rc < 0) { perror("fork"); exit(1); } if (rc > 0) { lf_init_completed(listen_sock); perlfilter(); } signal(SIGCHLD, reap_children); lf_init_completed(listen_sock); while (read(0, &buffer, 1) != 0) { ; } wait_restore(); /* Wait for all child processes to terminate */ while (wait(&waitstat) > 0) ; exit(0); return (0); }