Exemple #1
0
void
getfilenoise (datasink *dst, const char *path, cbv cb, size_t maxbytes)
{
  int fds[2];
  if (pipe (fds) < 0)
    fatal ("pipe: %m\n");
  pid_t pid = afork ();

  if (pid == -1)
    (*cb) ();
  else if (!pid) {
    close (fds[0]);
    int fd = open (path, O_RDONLY|O_NONBLOCK, 0);
    if (fd < 0) {
      fatal ("%s: %m\n", path);
      _exit (1);
      return;
    }
    for (;;) {
      char buf[1024];
      size_t n = read (fd, buf, min (maxbytes, sizeof (buf)));
      if (n <= 0)
	_exit (0);
      v_write (fds[1], buf, n);
      maxbytes -= n;
      if (!maxbytes)
	_exit (0);
    }
  }
  else {
    close (fds[1]);
    close_on_exec (fds[0]);
    getprognoise (dst, fds[0], pid, cb);
  }
}
Exemple #2
0
static void
sigcatch (int sig)
{
  sigdocheck = 1;
  sigcaught[sig] = 1;
  selwait.tv_sec = selwait.tv_usec = 0;
  /* On some operating systems, select is not a system call but is
   * implemented inside libc.  This may cause a race condition in
   * which select ends up being called with the original (non-zero)
   * value of selwait.  We avoid the problem by writing to a pipe that
   * will wake up the select. */
  v_write (sigpipes[1], "", 1);
}
Exemple #3
0
pid_t
spawn (const char *path, char *const *argv,
       int in, int out, int err, cbv::ptr postforkcb, char *const *env)
{
  int fds[2];

  if (pipe (fds) < 0)
    return -1;

  close_on_exec (fds[0]);
  close_on_exec (fds[1]);

  pid_t pid = afork ();
  if (pid < 0)
    return pid;

  if (!pid) {
    amain_panic = true;
    close (fds[0]);
    setstdfds (in, out, err);
    if (postforkcb)
      (*postforkcb) ();
    if (env)
      execve (path, argv, env);
    else
      execv (path, argv);

    int saved_err = errno;
    v_write (fds[1], &saved_err, sizeof (saved_err));
    close (fds[1]);
    // Since we return a useful errno, there is no need to print
    // anything in the child process.  Just exit.
    _exit (1);
  }

  close (fds[1]);
  int chld_err;
  int n = read (fds[0], &chld_err, sizeof (chld_err));
  close (fds[0]);

  if (n == 0)
    return pid;
  errno = chld_err;
  return -1;
}