Я пытался использовать системный вызов pipe () для создания оболочки, поддерживающей конвейерную передачу (с произвольным числом команд).
К сожалению, мне не особо повезло с использованием pipe (). Потратив несколько дней на просмотр различных онлайн-ресурсов, я решил собрать слишком упрощенную программу, которая дает тот же эффект, что и выполнение ls | sort
, чтобы посмотреть, смогу ли я даже заставить канал работать для двух дочерних, дочерних процессов. Вот код:
#include <sys/wait.h>
#include <unistd.h>
void run(char *cmd) {
char *args[2];
args[0] = cmd;
args[1] = NULL;
execvp(cmd, args);
}
int main(void) {
int filedes[2];
pipe(filedes);
pid_t pid_a, pid_b;
if (!(pid_a = fork())) {
dup2(filedes[1], 1);
run("ls");
}
if (!(pid_b = fork())) {
dup2(filedes[0], 0);
run("sort");
}
waitpid(pid_a, NULL, 0);
waitpid(pid_b, NULL, 0);
return 0;
}
Канал создается в родительском объекте, и я знаю, что после вызова execvp () каждый дочерний процесс наследует файловые дескрипторы, которые pipe () создает в родительском объекте. Для процесса ls
я использую dup2 () для перенаправления его стандартного out (1) на конец записи канала, а для процесса sort
стандарт в (0) перенаправляется на чтение конец трубы.
Наконец, я ожидаю завершения обоих процессов, прежде чем выйти.
Моя интуиция говорит мне, что это должно работать, но это не так!
Есть предложения?