Exemple #1
0
int
noise_from_prog::execprog (const char *const *av)
{
  int fds[2];
  if (pipe (fds) < 0)
    fatal ("pipe: %m\n");
  pid = afork ();

  if (!pid) {
    close (fds[0]);
    if (fds[1] != 1)
      dup2 (fds[1], 1);
    if (fds[1] != 2)
      dup2 (fds[1], 2);
    if (fds[1] != 1 && fds[1] != 2)
      close (fds[1]);
    close (0);
    rc_ignore (chdir ("/"));
    open ("/dev/null", O_RDONLY);

    char *env[] = { NULL };
    execve (av[0], const_cast<char *const *> (av), env);
    //warn ("%s: %m\n", av[0]);
    _exit (1);
  }

  close (fds[1]);
  close_on_exec (fds[0]);
  return fds[0];
}
Exemple #2
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 #3
0
str
agent_userdir (u_int32_t uid, bool create)
{
  int fd = open (".", O_RDONLY);
  if (fd < 0) {
    warn ("current working directory (.): %m\n");
    return NULL;
  }

  const char *tmpdir = safegetenv ("TMPDIR");
  if (!tmpdir || tmpdir[0] != '/')
    tmpdir = "/tmp";
  
  str ret;
  struct stat sb;
  uid_t myuid = getuid ();

  if (chdir (tmpdir) < 0)
    warn ("%s: %m\n", tmpdir);
  else if (stat (".", &sb) < 0)
    warn ("%s: %m\n", tmpdir);
  else if ((sb.st_mode & 022) && !(sb.st_mode & 01000))
    warn ("bad permissions on %s; chmod +t or set TMPDIR elsewhere", tmpdir);
  else if (myuid == uid)
    ret = agent_userdir_search (tmpdir, uid, create);
  else if (!myuid) {
    int fds[2];
    if (pipe (fds) < 0)
      warn ("pipe: %m\n");
    else if (pid_t pid = afork ()) {
      close (fds[1]);
      strbuf sb;
      while (sb.tosuio ()->input (fds[0]) > 0)
	;
      close (fds[0]);
      int status = 1;
      if (!waitpid (pid, &status, 0) && !status)
	ret = sb;
    }
    else {
      close (fds[0]);
      _exit (setuid (uid)
	     || !(ret = agent_userdir_search (tmpdir, uid, create))
	     || (write (fds[1], ret, ret.len ())
	         != implicit_cast<ssize_t> (ret.len ())));
    }
  }

  rc_ignore (fchdir (fd));
  close (fd);
  return ret ? str (strbuf ("%s/", tmpdir) << ret) : str (NULL);
}
Exemple #4
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;
}
Exemple #5
0
pid_t
aspawn (const char *path, char *const *argv,
	int in, int out, int err, cbv::ptr postforkcb, char *const *env)
{
  pid_t pid = afork ();
  if (pid < 0)
    return pid;

  if (pid)
    return pid;

  setstdfds (in, out, err);

  if (postforkcb)
    (*postforkcb) ();
  if (env)
    execve (path, argv, env);
  else
    execv (path, argv);

  warn ("%s: %m\n", path);
  _exit (1);
}