Я пытаюсь реализовать базовую оболочку в C, которая обрабатывает несколько каналов.Он ожидает ввода и выполняет команды в цикле for.Когда он получает EOF, он перестает ждать ввода и выходит.
В данный момент моя оболочка выводит правильный вывод при вводе конвейерной команды, например, ls | wc | grep ...
, но перестает ждать ввода и завершаетсявнешний цикл while вместо ожидания следующей строки ввода.
Я обнаружил, что это происходит из-за того, что fgets в моем цикле while возвращает ноль (stdin как-то получает EOF?).Я не получаю никаких ошибок при создании разветвления, создании канала или исключении.
Однако, если я ввожу одну команду за раз без каких-либо каналов, например, ls
, она успешно выведет правильный вывод и ожидает следующую строку ввода, как и должно быть.
Моя программа разбирает каждую строку ввода в struct
перед попыткой выполнения каждой команды (опущено ниже).struct
разработан таким образом, что я могу легко передать проанализированные аргументы в execvp
, который я не буду здесь описывать.
Это сильно упрощенная версия моего кода, в которой большая часть проверки ошибок опущена:
FILE* input;
char line[MAX_LINE];
input = stdin;
printf("> ");
fflush(stdout);
while (fgets(line, sizeof(line), input)) {
int i;
struct cmdLine;
/* struct defined elsewhere
** commands = # of commands in parsed input
** start = index where a command and its args start
** args[] = array holding each command/arg
*/
/* parse input line into cmdLine */
...
/* exec all commands in pipeline except the last */
for (i = 0; i < cmdLine.commands-1; ++i) {
int pd[2];
pipe(pd);
if (fork() == 0) {
dup2(pd[1], 1);
execvp(cmdLine.args[cmdLine.start[i]], &(cmdLine.args[cmdLine.start[i]]));
} else {
wait(NULL);
}
dup2(pd[0], 0);
close(pd[1]);
}
/* exec last command */
if (fork() == 0) {
execvp(cmdLine.args[cmdLine.start[i]], &(cmdLine.args[cmdLine.start[i]]));
} else {
wait(NULL);
}
if (stdin == input) {
printf("> "); /* print shell prompt */
fflush(stdout);
}
}
Я почти уверен, что где-то напутал со своим обманом, но я пытался часами, и я не понимаю, что я делаю неправильно.EOF как-то отправляется на стандартный ввод, так что fgets
возвращает NULL
?