Когда вы анализируете перенаправления (например, <
, >
, >>
) и выполняете open/dup2
, вам нужно удалить их из списка аргументов, который вы передаете execvp
.
Итак, учитывая ваш args
, вам необходим список аргументов second (например, args_clean
), который вы only копируете по имени программы и ее аргументам.
И вам нужно дополнительное приращение j
, чтобы пропустить файл перенаправления в args
(то есть просто сделать j + 1
не эквивалентно).
Вот очищенный дочерний код [прошу прощения за бесполезную очистку в стиле]:
char *args_clean[size];
int cleanidx = 0;
for (int j = 0; j < size; j++) {
if (!strcmp(args[j], "<")) { // looking for input character
++j;
if ((in = open(args[j], O_RDONLY)) < 0) { // open file for reading
fprintf(stderr, "error opening file\n");
}
dup2(in, STDIN_FILENO); // duplicate stdin to input file
close(in); // close after use
continue;
} // end input chech
if (!strcmp(args[j], ">")) { // looking for output character
++j;
out = creat(args[j], 0644); // create new output file
dup2(out, STDOUT_FILENO); // redirect stdout to file
close(out); // close after usere
continue;
} // end output check
if (!strcmp(args[j], ">>")) { // looking for append
++j;
int append = open(args[j], O_CREAT | O_RDWR | O_APPEND, 0644);
dup2(append, STDOUT_FILENO);
close(append);
continue;
}
args_clean[cleanidx++] = args[j];
} // end loop
args_clean[cleanidx] = NULL;
execvp(args_clean[0], args_clean); // execute in parent
fprintf(stderr, "error in child execi \n"); // error
exit(0);
Также, смотрите мой ответ здесь о чем-то похожем с каналами: утечка fd, пользовательская оболочка
И, для полной оболочки, см. Мой ответ: Реализация перенаправления ввода / вывода в оболочке Linux с использованием C и посмотрите на встроенную ссылку для вставки