Перенаправление вывода разветвленного процесса на родительский процесс в C - PullRequest
2 голосов
/ 01 октября 2010

Я реализую (более простую) версию bash. Одна из задач - принять команду:

$ bg <command> <arguments>

Затем будет запущен новый процесс, а затем запущен execvp() в новом процессе с использованием <command> и <arguments> в качестве параметров. Проблема в том, что когда я получаю выходные данные дочернего процесса, я использую pipe(), и после получения выходных данных дочернего процесса и вывода его, когда я хочу, я не могу переключиться обратно на STDIN родительский (shell) процесс, который приводит к segfault в следующий раз, когда мне нужно принять ввод.

Вот часть моей функции "bg".

ChildPID = fork();
if (ChildPID < 0) {
 /* There is an error */
 printf("Error forking the process.\n");
 exit(1);
}
if (ChildPID >= 0) {
 if (ChildPID == 0) {  /* Child Process */
  close(m_pipefd[0]);
  dup2(m_pipefd[1], STDOUT_FILENO);
  close(m_pipefd[1]);
  //sleep(5);
         err = execvp(optionsPTR[0], optionsPTR);
  switch (errno) {
   case ENOENT:
    printf("RSI: %s: command not found\n", optionsPTR[0]);
    break;
   case EACCES:
    printf("RSI: %s: Permission denied\n", optionsPTR[0]);
    break;
  }
  exit(1);
 }
 else {  /* Parent Process */
  WaitErr = waitpid(ChildPID, &status, WNOHANG | WUNTRACED);
                return(0); /* to main */
        }
}
return 0;

И код, когда я получаю вывод из канала после завершения процесса.

close(m_pipefd[1]);     
dup2(m_pipefd[0], STDIN_FILENO);
while(fgets(buffer, sizeof(buffer), stdin)) {
 buf = buffer;
 printf("%s\n", buf);
}
close(m_pipefd[0]);

Таким образом, версия tl; dr состоит в том, что мне нужно сбросить обратно в stdin для родительского процесса после захвата вывода дочерних процессов.

Спасибо

Брейден

1 Ответ

3 голосов
/ 01 октября 2010

Обычно нет необходимости связываться с stdin и stdout у вашего родителя. После того, как вы подключите свои каналы в child к stdin и stdout, другие концы каналов должны иметь возможность отправлять данные или получать данные от дочернего.

Просто прочитайте из m_pipefd [1] в вашем родителе.

...