Я реализую (более простую) версию 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 для родительского процесса после захвата вывода дочерних процессов.
Спасибо
Брейден