Exemplo n.º 1
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;
}
Exemplo n.º 2
0
Arquivo: init.c Projeto: arsv/sninit
static int setup(int argc, char** argv)
{
	setargs(argc, argv);

	if(setstdfds())
		retwarn(-1, "cannot set initial fds 0, 1, 2");

	if(setinitctl())
		/* Not having telinit is bad, but aborting system startup
		   for this mere reason is likely even worse. */
		warn("can't initialize initctl, init will be uncontrollable");

	if(setsignals())
		retwarn(-1, "failed to set signal handlers");

	if(!configure(NONSTRICT))
		setnewconf();
	else if(!cfg)
		retwarn(-1, "initial configuration error");

	return 0;
}
Exemplo n.º 3
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);
}