Exemplo n.º 1
0
ssize_t
ath_waitpid (pid_t pid, int *status, int options)
{
  return pth_waitpid (pid, status, options);
}
Exemplo n.º 2
0
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;
}