static void
proc_forkwait(struct proc *p, const char *file, char **argv)
{
  int retryEINTR = 0, retryEAGAIN = 0;
  pid_t pid;

restart:
  switch(pid = fork()) {
  case -1:
    switch(errno) {
    case EINTR:
      if (++retryEINTR > NPROC + 1) {
        _log_fork(LOG_INFO, errno, file);
      }
      goto restart;
    case EAGAIN:
      if (++retryEAGAIN <= RETRY_SYSCALL) {
        _log_fork(LOG_INFO, errno, file);
        pause_syscall(retryEAGAIN);
        goto restart;
      }
      /* down seems more likely */
    default:
      die_fork(errno, file);
    }
  case 0:
    proc_child(p, file, argv);

  default:
    p->pid = pid;
    proc_parent(p);
  }
}
Beispiel #2
0
void doanddie(char *user, unsigned int userlen /* including 0 byte */,
    char *pass)
{
  int child;
  int wstat;
  int pi[2];
 
  close(3);
  if (pipe(pi) == -1) die_pipe();
  if (pi[0] != 3) die_pipe();
  switch(child = fork()) {
    case -1:
      die_fork();
    case 0:
      close(pi[1]);
      sig_pipedefault();
      execvp(*childargs,childargs);
      _exit(1);
  }
  close(pi[0]);
  substdio_fdbuf(&ssup,subwrite,pi[1],upbuf,sizeof upbuf);
  if (substdio_put(&ssup,user,userlen) == -1) die_write();
  if (substdio_put(&ssup,pass,str_len(pass) + 1) == -1) die_write();
  if (substdio_puts(&ssup,"<") == -1) die_write();
  if (substdio_puts(&ssup,unique) == -1) die_write();
  if (substdio_puts(&ssup,hostname) == -1) die_write();
  if (substdio_put(&ssup,">",2) == -1) die_write();
  if (substdio_flush(&ssup) == -1) die_write();
  close(pi[1]);
  byte_zero(pass,str_len(pass));
  byte_zero(upbuf,sizeof upbuf);
  if (wait_pid(&wstat,child) == -1) die();
  if (wait_crashed(wstat)) die_childcrashed();
  switch (wait_exitcode(wstat)) {
    case 0: die();
    case 1: die_1();
    case 2: die_2();
    case 25: die_25();
    case 3: die_3();
    case 4: die_4();
    case 5: die_5();
    case 6: die_6();
    case 61: die_61();
    case 62: die_62();
    case 7: die_7();
    case 8: die_nomem();
    default: die_unknown();
  }
  die();
}