Реализация труб - PullRequest
       8

Реализация труб

9 голосов
/ 17 апреля 2010

Я пытаюсь реализовать оболочку linux, которая поддерживает трубопровод. Я уже выполнил простые команды, команды, работающие в фоновом режиме, перенаправления, но конвейер все еще отсутствует.

Я уже читал об этом и видел некоторые фрагменты кода, но все еще не смог разобраться в работающем решении.

Что у меня так далеко:

int fd[2];

pipe(fd);

pid_t pid = fork();

if (pid == -1)  
   return -1;  

if (pid == 0)  
{  
   close(fd[1]); //close write to pipe, in child
   execlp("cat", "cat", "names.txt", NULL);
}

else
{
   close(fd[0]); //close read from pipe, in parent
   execlp("sort", "sort", NULL);
}  

Я начинающий программист, как вы, вероятно, можете сказать, и когда я программирую что-то, о чем мало что знаю, в этом, очевидно, дело, мне нравится начинать с чего-то действительно простого и конкретного, а затем строить оттуда ,

Итак, прежде чем я смогу реализовать три и более различных команд в конвейере, я хотел бы иметь возможность вычислить «ls names.txt | sort» или что-то похожее, в котором names.txt представляет собой файл имен, алфавитно неупорядоченный .

Обновленный код, но все еще не работает.

Спасибо.

Ответы [ 2 ]

11 голосов
/ 18 апреля 2010

Вам необходимо заменить стандартный вывод одного дочернего элемента записывающим концом канала, а стандартный ввод другого дочернего элемента - окончанием чтения:

if (pid == 0)  
{  
   close(fd[0]); //close read from pipe, in parent
   dup2(fd[1], STDOUT_FILENO); // Replace stdout with the write end of the pipe
   close(fd[1]); // Don't need another copy of the pipe write end hanging about
   execlp("cat", "cat", "names.txt", NULL);
}
else
{
   close(fd[1]); //close write to pipe, in child
   dup2(fd[0], STDIN_FILENO); // Replace stdin with the read end of the pipe
   close(fd[0]); // Don't need another copy of the pipe read end hanging about
   execlp("sort", "sort", NULL);
} 
4 голосов
/ 17 апреля 2010

Посмотрите на <a href="http://linux.die.net/man/2/pipe" rel="nofollow noreferrer">pipe()</a> стандартный вызов библиотеки. Это используется для создания трубы. Конечно, вы должны выполнить часть работы до you fork(), чтобы дочерний процесс мог правильно наследовать дескриптор файла.

Также обратите внимание на порядок аргументов <a href="http://linux.die.net/man/2/dup" rel="nofollow noreferrer">dup2()</a>:

int dup2(int oldfd, int newfd);

dup2 () делает newfd копией oldfd, при необходимости сначала закрывая newfd

...