ssize_t ath_waitpid (pid_t pid, int *status, int options) { return pth_waitpid (pid, status, options); }
void* dnsrv_process_io(void* threadarg) { /* Get DNS IO info */ dns_io di = (dns_io)threadarg; int retcode = 0; int pid = 0; int readlen = 0; char readbuf[1024]; xstream xs = NULL; sigset_t sigs; #ifdef __CYGWIN__ dns_resend_list iternode = NULL; #endif sigemptyset(&sigs); sigaddset(&sigs, SIGHUP); sigprocmask(SIG_BLOCK, &sigs, NULL); /* Allocate an xstream for talking to the process */ xs = xstream_new(di->mempool, dnsrv_process_xstream_io, di); /* Transmit root element to coprocess */ pth_write(di->out, "<stream>", 8); /* Transmit resend entries to coprocess */ #ifdef __CYGWIN__ iternode = di->svclist; while (iternode != NULL) { if (iternode->service) { sprintf(readbuf, "<resend service=\"%s\">%s</resend>", iternode->service, iternode->host); } else { sprintf(readbuf, "<resend>%s</resend>", iternode->host); } pth_write(di->out, readbuf, strlen(readbuf)); iternode = iternode->next; } #endif /* Loop forever */ while (1) { /* Hostname lookup completed from coprocess */ readlen = pth_read(di->in, readbuf, sizeof(readbuf)); if (readlen <= 0) { log_debug(ZONE,"dnsrv: Read error on coprocess: %d %s",errno,strerror(errno)); break; } if (xstream_eat(xs, readbuf, readlen) > XSTREAM_NODE) break; } /* If we reached this point, the coprocess probably is dead, so process the SIG_CHLD */ pid = pth_waitpid(di->pid, &retcode, 0); if(pid == -1) { log_debug(ZONE, "pth_waitpid returned -1: %s", strerror(errno)); } else if(pid == 0) { log_debug(ZONE, "no child available to call waitpid on"); } else { log_debug(ZONE, "pid %d, exit status: %d", pid, WEXITSTATUS(retcode)); } /* Cleanup */ close(di->in); close(di->out); di->out = 0; log_debug(ZONE,"child returned %d",WEXITSTATUS(retcode)); if(WIFEXITED(retcode)) /* if the child exited normally */ { log_debug(ZONE, "child being restarted..."); /* Fork out resolver function/process */ di->pid = dnsrv_fork_and_capture(dnsrv_child_main, di); /* Start IO thread */ pth_spawn(PTH_ATTR_DEFAULT, dnsrv_process_io, (void*)di); return NULL; } log_debug(ZONE, "child dying..."); return NULL; }