Пример #1
0
pid_t PseudoTTYSpawnFunction(int *ret_pty, BASIC_FUNC Func, void *Data, int Flags, const char *Config)
{
    pid_t pid=-1, ConfigFlags;
    int tty, pty, i;

    if (PseudoTTYGrab(&pty, &tty, Flags))
    {
        pid=xfork("");
        if (pid==0)
        {
            for (i=0; i < 3; i++) close(i);
            close(pty);

            setsid();
            ioctl(tty,TIOCSCTTY,0);

            dup(tty);
            dup(tty);
            dup(tty);

            ///now that we've dupped it, we don't need to keep it open
            //as it will be open on stdin/stdout
            close(tty);

            ConfigFlags=ProcessApplyConfig(Config);
            Func((char *) Data, ConfigFlags);
            _exit(0);
        }

        close(tty);
    }

    *ret_pty=pty;
    return(pid);
}
Пример #2
0
void time_main(void)
{
  pid_t pid;
  struct timeval tv, tv2;

  gettimeofday(&tv, NULL);
  if (!(pid = xfork())) xexec(toys.optargs);
  else {
    int stat;
    struct rusage ru;
    float r, u, s;

    wait4(pid, &stat, 0, &ru);
    gettimeofday(&tv2, NULL);
    if (tv.tv_usec > tv2.tv_usec) {
      tv2.tv_usec += 1000000;
      tv2.tv_sec--;
    }
    r = (tv2.tv_sec-tv.tv_sec)+((tv2.tv_usec-tv.tv_usec)/1000000.0);
    u = ru.ru_utime.tv_sec+(ru.ru_utime.tv_usec/1000000.0);
    s = ru.ru_stime.tv_sec+(ru.ru_stime.tv_usec/1000000.0);
    fprintf(stderr, "real %f\nuser %f\nsys %f\n", r, u, s);
    toys.exitval = WIFEXITED(stat) ? WEXITSTATUS(stat) : WTERMSIG(stat);
  }
}
Пример #3
0
void
sys_spawn_shell (void)
{
  pid_t child;
  const char *shell = getenv ("SHELL");
  if (! shell)
    shell = "/bin/sh";
  child = xfork ();
  if (child == 0)
    {
      priv_set_restore_linkdir ();
      execlp (shell, "-sh", "-i", NULL);
      exec_fatal (shell);
    }
  else
    {
      int wait_status;
      while (waitpid (child, &wait_status, 0) == -1)
	if (errno != EINTR)
	  {
	    waitpid_error (shell);
	    break;
	  }
    }
}
Пример #4
0
int	execute_pipe_start(t_tree *tree, t_shell *st_shell)
{
  int	flag;
  int	statut;
  int	fd[2];
  pid_t	pid;

  if ((flag = prepare_all_commands(tree, st_shell)) != EXIT_SUCCESS)
    return (flag);
  if ((pid = xfork()) == 0)
    {
      if (xpipe(fd) == -1)
	exit(EXIT_FAILURE);
      reset_line(st_shell);
      set_fd_out(tree->right, fd[1]);
      set_fd_in(tree->left, fd[0]);
      if (tree->right->type == IS_CMD)
	init_first_pipe(tree, st_shell, fd);
      init_first_pipe_spe(tree, st_shell, fd);
    }
  else if (pid > 0)
    {
      if (waitpid(-1, &statut, 0) == -1)
	perror("Waitpid() :");
      return (write_statut(statut));
    }
  return (FATAL_ERROR);
}
Пример #5
0
int
sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
{
  int p[2];
  char *argv[4];

  xpipe (p);
  pipe_handler = signal (SIGPIPE, SIG_IGN);
  global_pid = xfork ();

  if (global_pid != 0)
    {
      xclose (p[PREAD]);
      return p[PWRITE];
    }

  /* Child */
  xdup2 (p[PREAD], STDIN_FILENO);
  xclose (p[PWRITE]);

  stat_to_env (file_name, typechar, st);

  argv[0] = "/bin/sh";
  argv[1] = "-c";
  argv[2] = to_command_option;
  argv[3] = NULL;

  execv ("/bin/sh", argv);

  exec_fatal (file_name);
}
Пример #6
0
pid_t
sys_start_dedup_filter_child(void)
{
   pid_t cpid;

   if (dedup_filter_command_option == NULL)
    return -1;

   xpipe(dedup_filter_query_pipe);
   xpipe(dedup_filter_response_pipe);

   cpid = xfork();
   if (cpid > 0)
     {
       // parent tar
       // we write to query pipe, read from response pipe
       // so close the other fds
       xclose(dedup_filter_query_pipe[PREAD]);
       xclose(dedup_filter_response_pipe[PWRITE]);
       return cpid;
     }

   // child (filter) reads from query and writes to response
   // so close the rest
   xclose(dedup_filter_query_pipe[PWRITE]);
   xclose(dedup_filter_response_pipe[PREAD]);

   xdup2(dedup_filter_query_pipe[PREAD], STDIN_FILENO);
   xdup2(dedup_filter_response_pipe[PWRITE], STDOUT_FILENO);

   program_name = _("tar (child)");

   execlp(dedup_filter_command_option, NULL);

}
Пример #7
0
int	parse_command_for_pipe(char **command, int tab_len, int first)
{
  int	p[2];
  int	pid;
  int	ret;

  if (xpipe(p) < 0)
    return (0);
  if ((pid = xfork()) > 0)
    {
      ret = exec_father(command[tab_len - 1], p, pid, first);
      if (ret > 0)
	return (ret);
    }
  else
    {
      xclose(p[0]);
      xdup2(p[1], 1);
      if (tab_len > 2)
	parse_command_for_pipe(command, tab_len - 1, 0);
      else
	parse_command_redir(command[0]);
      exit(0);
    }
  return (pid);
}
Пример #8
0
BOOL	exec_pipes(t_pipes *p, t_info *info, FLAG son, FD pi[3])
{
  STATUS	status_quo;
  pid_t		pid;
  FD		w[2];

  if (!(pid = -(!((unsigned long)(p->next != NULL)))))
    {
      if (pipe(w) == -1)
	return (FALSE);
      if ((pid = xfork()) < 0)
	return (FALSE);
    }
  if (!pid)
    {
      init_pipe(w, pi, W_IN);
      exec_pipes(p->next, info, SON, pi);
      return (FALSE);
    }
  if (p->next)
    init_pipe(w, pi, W_OUT);
  if (exec_cmd(p->cmd, info, info->son = (son | (2 * (pid > 0))), pi) == FALSE)
    return (FALSE);
  my_wait(pid, &status_quo);
  if (pid < 0)
    return (TRUE);
  return (get_status(info, status_quo));
}
Пример #9
0
/*
 * Execute the program supplied on the command line. If restart was set
 * then send the child process SIGTERM and restart it.
 */
void
run_utility(char *argv[]) {
	int pid;
	int i, m;
	int ret, status;
	struct timespec delay = { 0, 1000000 };
	char **new_argv;
	char *p, *arg_buf;
	int argc;

	if (restart_opt == 1)
		terminate_utility();

	/* clone argv on each invocation to make the implementation of more
	 * complex subsitution rules possible and easy
	 */
	for (argc=0; argv[argc]; argc++);
	arg_buf = malloc(ARG_MAX);
	new_argv = calloc(argc+1, sizeof(char *));
	for (m=0, i=0, p=arg_buf; i<argc; i++) {
		new_argv[i] = p;
		if ((m < 1) && (strcmp(argv[i], "/_")) == 0) {
			p += strlen(xrealpath(leading_edge->fn, p));
			m++;
		}
		else
			p += strlcpy(p, argv[i], ARG_MAX - (p - arg_buf));
		p++;
	}

	pid = xfork();
	if (pid == -1)
		err(1, "can't fork");

	if (pid == 0) {
		if (clear_opt == 1)
			(void) system("/usr/bin/clear");
		/* Set process group so subprocess can be signaled */
		if (restart_opt == 1)
			setpgid(0, getpid());
		/* wait up to 1 seconds for each file to become available */
		for (i=0; i < 10; i++) {
			ret = xexecvp(new_argv[0], new_argv);
			if (errno == ETXTBSY) nanosleep(&delay, NULL);
			else break;
		}
		if (ret != 0)
			err(1, "exec %s", new_argv[0]);
	}
	child_pid = pid;

	if (restart_opt == 0)
		xwaitpid(pid, &status, 0);

	xfree(arg_buf);
	xfree(new_argv);
}
Пример #10
0
int	fork_in_the_word(t_info *info)
{
  if (xfork())
    return (-1);
  if (new_connection(info))
    exit(-1);
  enter_in_the_world(info);
  return (0);
}
Пример #11
0
static void
init_invalid_status (void)
{
  pid_t pid = xfork ();
  if (pid == 0)
    _exit (127);
  xwaitpid (pid, &invalid_status, 0);
  if (WIFEXITED (invalid_status))
    invalid_status = WEXITSTATUS (invalid_status);
}
Пример #12
0
void	lpwd()
{
  pid_t	pid;

  my_putstr("SUCCESS : Working Directory Path\n");
  pid = xfork();
  if (pid == 0)
    execlp("pwd", "pwd", NULL);
  else
    xwait(NULL);
  my_putstr("{ftp} ");
}
Пример #13
0
/* Calls fork() and on success returns its return value.  On failure, logs an
 * error and exits unsuccessfully.
 *
 * Post-fork, but before returning, this function calls a few other functions
 * that are generally useful if the child isn't planning to exec a new
 * process. */
static pid_t
fork_and_clean_up(void)
{
    pid_t pid = xfork();
    if (pid > 0) {
        /* Running in parent process. */
        fatal_signal_fork();
    } else if (!pid) {
        /* Running in child process. */
        lockfile_postfork();
    }
    return pid;
}
Пример #14
0
int xforkio(int StdIn, int StdOut, int StdErr)
{
    pid_t pid;
    int fd;

    pid=xfork("");
    if (pid==0)
    {
        if (StdIn > -1)
        {
            if (StdIn !=0)
            {
                close(0);
                dup(StdIn);
            }
        }
        else
        {
            fd=open("/dev/null",O_RDONLY);
            dup(fd);
            close(fd);
        }

        if (StdOut > -1)
        {
            if (StdOut !=1)
            {
                close(1);
                dup(StdOut);
            }
        }
        else
        {
            fd=open("/dev/null",O_WRONLY);
            dup(fd);
            close(fd);
        }

        if (StdErr > -1)
        {
            if (StdErr !=2)
            {
                close(2);
                dup(StdErr);
            }
        }
    }


    return(pid);
}
Пример #15
0
/* forking a child process to play the
 * losssless file */
void cue_play(const char *name)
{
	pid_t pid;
	pid = xfork();
	if (pid == 0) {
		execlp("mplayer", "mplayer", "-slave", "-quiet", name,
		       (char *)0);
		fprintf(stderr, "execlp failure: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	} else {
		usleep(100000);
		print_cue_index();
	}

	return;
}
Пример #16
0
void
sys_exec_checkpoint_script (const char *script_name,
			    const char *archive_name,
			    int checkpoint_number)
{
  pid_t pid;
  char *argv[4];
  char uintbuf[UINTMAX_STRSIZE_BOUND];

  pid = xfork ();

  if (pid != 0)
    {
      /* Master */

      int status;

      while (waitpid (pid, &status, 0) == -1)
	if (errno != EINTR)
	  {
	    waitpid_error (script_name);
	    break;
	  }

      return;
    }

  /* Child */
  setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
  setenv ("TAR_ARCHIVE", archive_name, 1);
  setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
  setenv ("TAR_BLOCKING_FACTOR",
	  STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
  setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
  setenv ("TAR_FORMAT",
	  archive_format_string (current_format == DEFAULT_FORMAT ?
				 archive_format : current_format), 1);
  argv[0] = "/bin/sh";
  argv[1] = "-c";
  argv[2] = (char*) script_name;
  argv[3] = NULL;

  execv (argv[0], argv);

  exec_fatal (script_name);
}
Пример #17
0
void FAST_FUNC open_transformer(int fd, const char *transform_prog)
#endif
{
	struct fd_pair fd_pipe;
	int pid;

	xpiped_pair(fd_pipe);
	pid = BB_MMU ? xfork() : xvfork();
	if (pid == 0) {
		/* Child */
		close(fd_pipe.rd); /* we don't want to read from the parent */
		// FIXME: error check?
#if BB_MMU
		{
			transformer_aux_data_t aux;
			init_transformer_aux_data(&aux);
			aux.check_signature = check_signature;
			transformer(&aux, fd, fd_pipe.wr);
			if (ENABLE_FEATURE_CLEAN_UP) {
				close(fd_pipe.wr); /* send EOF */
				close(fd);
			}
			/* must be _exit! bug was actually seen here */
			_exit(EXIT_SUCCESS);
		}
#else
		{
			char *argv[4];
			xmove_fd(fd, 0);
			xmove_fd(fd_pipe.wr, 1);
			argv[0] = (char*)transform_prog;
			argv[1] = (char*)"-cf";
			argv[2] = (char*)"-";
			argv[3] = NULL;
			BB_EXECVP(transform_prog, argv);
			bb_perror_msg_and_die("can't execute '%s'", transform_prog);
		}
#endif
		/* notreached */
	}

	/* parent process */
	close(fd_pipe.wr); /* don't want to write to the child */
	xmove_fd(fd_pipe.rd, fd);
}
Пример #18
0
void	lls(char *buffer)
{
  char	opt[CMD];
  char	*pointer;
  pid_t	pid;

  get_info_c(opt, buffer, my_strlen(buffer));
  pointer = opt;
  if (opt[0] == '\0')
    pointer = NULL;
  my_putstr("SUCCESS : Working Listing\n");
  pid = xfork();
  if (pid == 0)
    execlp("/bin/sh", "sh", "-c", "ls -la", NULL);
  else
    xwait(NULL);
  my_putstr("{ftp} ");
}
Пример #19
0
static int	manage_fork(t_fifo_elem *cur, t_sllist **myenv, int *status)
{
  cur->data.pid = xfork();
  if (!cur->data.pid)
    return (manage_child(cur, myenv));
  if (cur->data.flag[DSYNC])
    {
      printf("%s%d\n", BG_PRC, cur->data.pid);
      usleep(150);
    }
  else if (cur->data.pid > 0 &&
	   (!F_ISPIPE(cur->data.flag[OUT]) ||
	    !cur->next))
    {
      xwaitpid(cur->data.pid, status, 0);
      manage_status(cur, *status);
    }
  return (EXIT_SUCCESS);
}
Пример #20
0
/* Spawn a subprocess to send two signals: First SIGUSR1, then
   SIGUSR2.  Return the PID of the process.  */
static pid_t
signal_sender (void)
{
  pid_t pid = xfork ();
  if (pid == 0)
    {
      static const struct timespec delay = { 1, };
      if (nanosleep (&delay, NULL) != 0)
        FAIL_EXIT1 ("nanosleep: %m");
      if (kill (getppid (), SIGUSR1) != 0)
        FAIL_EXIT1 ("kill (SIGUSR1): %m");
      if (nanosleep (&delay, NULL) != 0)
        FAIL_EXIT1 ("nanosleep: %m");
      if (kill (getppid (), SIGUSR2) != 0)
        FAIL_EXIT1 ("kill (SIGUSR2): %m");
      _exit (0);
    }
  return pid;
}
void		ls(t_server *serv, char *cmd)
{
  int		oldfd;
  pid_t		pid;

  (void)cmd;
  swrite(serv->cfd, "150 ASCII data connection\r\n");

  oldfd = dup(1);
  dup2(serv->data->cfd, 1);
  pid = xfork(serv->data->cfd);
  if (pid == 0)
    execl("/bin/ls", "ls", "-l", NULL);
  else
    waitpid(pid, 0, WSTOPPED);
  dup2(oldfd, 1);
  close(serv->data->cfd);

  swrite(serv->cfd, "226 ASCII Transfert completed\r\n");
}
Пример #22
0
int	execute_last_command(t_tree *tree, t_shell *st_shell)
{
  int	statut;
  pid_t	pid;

  if (is_builtin(tree->args[0]))
    return (check_builtins(st_shell, tree));
  if ((pid = xfork()) == 0)
    {
      xdup2(tree->fd_in, 0);
      xdup2(tree->fd_out, 1);
      xexecve(tree->full_path, tree->args, st_shell->my_env);
    }
  else if (pid > 0)
    {
      if (waitpid(pid, &statut, 0) == -1)
	perror("Waitpid() :");
      else
	return (write_statut(statut));
    }
  return (FATAL_ERROR);
}
Пример #23
0
static int run_foreground_command(CmdCmpList list)
{
    Command cmd = cmdline_component_at_index(list, 0)->content.cmd;
    
    if ( !execute_builtin(cmd) ) {
        const pid_t pid = xfork();

        if ( pid == 0 ) {
            char ** args = command_raw_args(cmd);
            execvp(args[0], args);

            switch ( errno ) {
                case EACCES:
                    fprintf(stderr, "pgshell: %s: Permission denied\n",
                            args[0]);
                    break;

                case ENOENT:
                    fprintf(stderr, "pgshell: %s: No such file or directory\n",
                            args[0]);
                    break;

                default:
                    fprintf(stderr, "pgshell: other exec() error\n");
                    break;
            }

            cmdline_destroy(list);
            exit(EXIT_FAILURE);
        }

        int status;
        waitpid(pid, &status, 0);
        return status;
    }

    return 0;
}
Пример #24
0
int
sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
{
  int p[2];

  xpipe (p);
  pipe_handler = signal (SIGPIPE, SIG_IGN);
  global_pid = xfork ();

  if (global_pid != 0)
    {
      xclose (p[PREAD]);
      return p[PWRITE];
    }

  /* Child */
  xdup2 (p[PREAD], STDIN_FILENO);
  xclose (p[PWRITE]);

  stat_to_env (file_name, typechar, st);

  priv_set_restore_linkdir ();
  xexec (to_command_option);
}
Пример #25
0
void	ftrace_fork(ptraceData *data)
{
	pid_t			pid;
	char 			**tab;

	printf("Running %s\n", data->command);
	tab = my_str_to_wordtab2(data->command);
	pid = xfork();
	if (!pid)
	{

	  	ptrace(PT_TRACE_ME, 0, NULL, 0);
		perror("ptrace fork");
		errno = 0;
		execvpe(tab[0], tab, environ);
		perror(data->command);
		puts(tab[0]);
        printf("==\n");
	}
	else
	{
		loop(data, pid, 0);
	}
}
Пример #26
0
int		gere_left(t_info *info, char *str, int flag)
{
  int		pid;
  int		value;

  if (flag == CHILD)
    {
      value = gere_left_next(info, str, flag);
      exit(value);
    }
  else
    {
      if ((pid = xfork()) == -1)
	return (status(info, EXIT_FAILURE));
      if (pid == 0)
	{
	  value = gere_left_next(info, str, flag);
	  exit(value);
	}
      else if (xwaitpid(pid, &value, 0) == EXIT_FAILURE)
	return (status(info, EXIT_FAILURE));
    }
  return (EXIT_SUCCESS);
}
Пример #27
0
int
sys_exec_info_script (const char **archive_name, int volume_number)
{
  pid_t pid;
  char *argv[4];
  char uintbuf[UINTMAX_STRSIZE_BOUND];
  int p[2];
  static RETSIGTYPE (*saved_handler) (int sig);
  
  xpipe (p);
  saved_handler = signal (SIGPIPE, SIG_IGN);

  pid = xfork ();

  if (pid != 0)
    {
      /* Master */

      int rc;
      int status;
      char *buf = NULL;
      size_t size = 0;
      FILE *fp;

      xclose (p[PWRITE]);
      fp = fdopen (p[PREAD], "r");
      rc = getline (&buf, &size, fp);
      fclose (fp);

      if (rc > 0 && buf[rc-1] == '\n')
	buf[--rc] = 0;

      while (waitpid (pid, &status, 0) == -1)
	if (errno != EINTR)
	  {
	    signal (SIGPIPE, saved_handler);
	    waitpid_error (info_script_option);
	    return -1;
	  }

      signal (SIGPIPE, saved_handler);
      
      if (WIFEXITED (status))
	{
	  if (WEXITSTATUS (status) == 0 && rc > 0)
	    *archive_name = buf;
	  else
	    free (buf);
	  return WEXITSTATUS (status);
	}

      free (buf);
      return -1;
    }

  /* Child */
  setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
  setenv ("TAR_ARCHIVE", *archive_name, 1);
  setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
  setenv ("TAR_BLOCKING_FACTOR",
	  STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
  setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
  setenv ("TAR_FORMAT",
	  archive_format_string (current_format == DEFAULT_FORMAT ?
				 archive_format : current_format), 1);
  setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);

  xclose (p[PREAD]);

  argv[0] = "/bin/sh";
  argv[1] = "-c";
  argv[2] = (char*) info_script_option;
  argv[3] = NULL;

  execv (argv[0], argv);

  exec_fatal (info_script_option);
}
Пример #28
0
/* Open directory 'BDMV', change directory to it.
 * Then open directory 'STREAM', change directory to it.
 * Get the filename has the biggest size in it.
 */
int bluray(const char *dir_name)
{
	DIR *dir;
	struct stat buf;
	struct dirent *dirp;
	char *rval = NULL;
	pid_t pid;

	if (!dir_name || !*dir_name)
		return -1;

	if (is_absolute_path(dir_name)) {
		xchdir(dir_name);
		dir = opendir(BLURAY_PATH);
		if (dir == NULL) {
			fprintf(stderr, "\nopen directory '%s' failure: %s\n",
				BLURAY_PATH, strerror(errno));
			xchdir(dir_name);
			xchdir("..");
			return -1;
		}
		xchdir(BLURAY_PATH);

		while ((dirp = readdir(dir)) != NULL) {
			xstat(dirp->d_name, &buf);
			if ((buf.st_size / 1024 / 1024) > FILE_SIZE) {
				size_t len = strlen(dirp->d_name) + 1;
				rval = xmalloc(len);
				strncpy(rval, dirp->d_name, len);
			}
		}
	} else {
		dir = opendir(BLURAY_PATH);
		if (dir == NULL) {
			fprintf(stderr, "\nopen directory '%s' failure: %s\n",
				BLURAY_PATH, strerror(errno));
			return -1;
		}
		xchdir(BLURAY_PATH);

		while ((dirp = readdir(dir)) != NULL) {
			xstat(dirp->d_name, &buf);
			if ((buf.st_size / 1024 / 1024) > FILE_SIZE) {
				size_t len = strlen(dirp->d_name) + 1;
				rval = xmalloc(len);
				strncpy(rval, dirp->d_name, len);
			}
		}
	}

	pid = xfork();
	if (pid == 0) {
		execlp("mplayer", "mplayer", rval, (char *)0);
		perror("execlp error");
		exit(EXIT_FAILURE);
	}

	xchdir(dir_name);
	xchdir("..");
	return 0;
}
void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
{
	file_header_t *file_header = archive_handle->file_header;

#if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */
	char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
	if (!sctx)
		sctx = archive_handle->tar__sctx[PAX_GLOBAL];
	if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
		setfscreatecon(sctx);
		free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
		archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
	}
#endif

	if ((file_header->mode & S_IFMT) == S_IFREG) {
		pid_t pid;
		int p[2], status;
		char *tar_env[TAR_MAX];

		memset(tar_env, 0, sizeof(tar_env));

		xpipe(p);
		pid = BB_MMU ? xfork() : xvfork();
		if (pid == 0) {
			/* Child */
			/* str2env(tar_env, TAR_FILETYPE, "f"); - parent should do it once */
			oct2env(tar_env, TAR_MODE, file_header->mode);
			str2env(tar_env, TAR_FILENAME, file_header->name);
			str2env(tar_env, TAR_REALNAME, file_header->name);
#if ENABLE_FEATURE_TAR_UNAME_GNAME
			str2env(tar_env, TAR_UNAME, file_header->tar__uname);
			str2env(tar_env, TAR_GNAME, file_header->tar__gname);
#endif
			dec2env(tar_env, TAR_SIZE, file_header->size);
			dec2env(tar_env, TAR_UID, file_header->uid);
			dec2env(tar_env, TAR_GID, file_header->gid);
			close(p[1]);
			xdup2(p[0], STDIN_FILENO);
			signal(SIGPIPE, SIG_DFL);
			execl(archive_handle->tar__to_command_shell,
				archive_handle->tar__to_command_shell,
				"-c",
				archive_handle->tar__to_command,
				NULL);
			bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
		}
		close(p[0]);
		/* Our caller is expected to do signal(SIGPIPE, SIG_IGN)
		 * so that we don't die if child don't read all the input: */
		bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size);
		close(p[1]);

		if (safe_waitpid(pid, &status, 0) == -1)
			bb_perror_msg_and_die("waitpid");
		if (WIFEXITED(status) && WEXITSTATUS(status))
			bb_error_msg_and_die("'%s' returned status %d",
				archive_handle->tar__to_command, WEXITSTATUS(status));
		if (WIFSIGNALED(status))
			bb_error_msg_and_die("'%s' terminated on signal %d",
				archive_handle->tar__to_command, WTERMSIG(status));

		if (!BB_MMU) {
			int i;
			for (i = 0; i < TAR_MAX; i++) {
				if (tar_env[i])
					bb_unsetenv_and_free(tar_env[i]);
			}
		}
	}

#if 0 /* ENABLE_FEATURE_TAR_SELINUX */
	if (sctx)
		/* reset the context after creating an entry */
		setfscreatecon(NULL);
#endif
}
Пример #30
0
/* This creates a child process that we can talk to using a couple of pipes*/
pid_t PipeSpawnFunction(int *infd, int *outfd, int *errfd, BASIC_FUNC Func, void *Data, const char *Config)
{
    pid_t pid;
    int channel1[2], channel2[2], channel3[2], DevNull=-1;
    int Flags;

    if (infd) pipe(channel1);
    if (outfd) pipe(channel2);
    if (errfd) pipe(channel3);

    pid=xfork("");
    if (pid==0)
    {
        /* we are the child */
        if (infd) close(channel1[1]);
        else if (DevNull==-1) DevNull=open("/dev/null",O_RDWR);
        if (outfd) close(channel2[0]);
        else if (DevNull==-1) DevNull=open("/dev/null",O_RDWR);
        if (errfd) close(channel3[0]);
        else if (DevNull==-1) DevNull=open("/dev/null",O_RDWR);

        /*close stdin, stdout and stderr*/
        close(0);
        close(1);
        close(2);
        /*channel 1 is going to be our stdin, so we close the writing side of it*/
        if (infd) dup(channel1[0]);
        else dup(DevNull);
        /* channel 2 is stdout */
        if (outfd) dup(channel2[1]);
        else dup(DevNull);
        /* channel 3 is stderr */
        if (errfd)
        {
            //Yes, we can pass an integer value as errfd, even though it's an int *.
            //This is probably a bad idea, and will likely be changed in future releases
            //if (errfd==(int *) COMMS_COMBINE_STDERR) dup(channel2[1]);
            //else
            dup(channel3[1]);
        }
        else dup(DevNull);


        Flags=ProcessApplyConfig(Config);
        Func(Data, Flags);
        exit(0);
    }
    else // This is the parent process, not the spawned child
    {
        /* we close the appropriate halves of the link */
        if (infd)
        {
            close(channel1[0]);
            *infd=channel1[1];
        }
        if (outfd)
        {
            close(channel2[1]);
            *outfd=channel2[0];
        }
        if (errfd)
        {
            close(channel3[1]);
            //Yes, we can pass an integer value as errfd, even though errfd is an int *.
            //This is probably a bad idea, and will likely be changed in future releases
            //if (errfd != (int *) COMMS_COMBINE_STDERR) *errfd=channel3[0];
        }
    }

    return(pid);
}