Перенаправление ввода и каналы

Я понимаю конвейер, где вы хотите запустить команду типа ls -l | туалет -л:

int pipes[2];
pipe(pipes); 

if (fork() == 0){ //first fork
  dup2(pipes[1],1); 
  close(pipes[0]);
  close(pipes[1]);

  execvp(arr1[0], arr1); //arr1[0] = "ls" and  arr1[1] = "-l" and arr1[2] = 0
  perror("Ex failed");
  exit(1);
}

if (fork() == 0){ //2nd fork
  close(pipes[1]);
  dup2(pipes[0],0); 
  close(pipes[0]);

  execvp(arr2[0], arr2); //arr2[0] = "wc" and  arr2[1] = "-l" and arr2[2] = 0
  perror("Ex failed");
  exit(1);
}

Но как бы вы включили перенаправление ввода и вывода? скажем, я хочу кота ‹ foo.txt | туалет -л

Я понимаю, что первый форк нужно модифицировать, но я не понимаю, что нужно (еще один dup2()?). Буду очень признателен за помощь.

Спасибо.


person user5832523    schedule 24.01.2016    source источник
comment
Чего вы ожидаете от dup2(pipes[1],[1]);? Это недопустимый синтаксис; Я так понимаю, вы имели в виду dup2(pipes[1], STDOUT_FILENO);?   -  person Filipe Gonçalves    schedule 24.01.2016
comment
Это была опечатка. Я исправлю это.   -  person user5832523    schedule 24.01.2016


Ответы (1)


Но как бы вы включили перенаправление ввода и вывода? скажем, я хочу кота ‹ foo.txt | туалет -л

В случае перенаправления ввода вы открываете файл для чтения, а затем используете dup2(2) для дублирования дескриптора файла в стандартный ввод. Дескриптор файла stdinSTDIN_FILENO, определенный в unistd.h. Итак, что-то вроде этого:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

// ...

filename = "foo.txt";
int fd;
if ((fd = open(filename, O_RDONLY)) == -1) {
    perror("open %s: %s\n", filename, strerror(errno));
    exit(EXIT_FAILURE);
}
if (dup2(fd, STDIN_FILENO) == -1) {
    perror("dup2: %s -> stdin: %s\n", filename, strerror(errno));
    exit(EXIT_FAILURE);
}
if (close(fd) == -1) {
    perror("close %s: %s\n", filename, strerror(errno));
    exit(EXIT_FAILURE);
}

// Now, reading from stdin will read from the file.
// Do the normal pipe operations here.

int pipes[2];
// ...

Обратите внимание, что в вашем коде нет обработки ошибок — ни одной — это очень плохо, потому что, когда что-то пойдет не так, вы проигнорируете это, и код загадочным образом рухнет. Почти каждая вызванная вами функция может вернуться с ошибкой; рассмотреть возможность обработки ошибки, чтобы четко показать пользователю, что и где пошло не так.

person Filipe Gonçalves    schedule 24.01.2016
comment
Кажется, это не работает. Я сделал именно так, как вы посоветовали. Open(), dup2() и затем закрыть мои две вилки без изменений. В форках не требуется дополнительный код? - person user5832523; 24.01.2016
comment
@user5832523 user5832523 код для разветвления должен оставаться без изменений. Пожалуйста, опубликуйте полный рабочий, компилируемый код, который, как вы утверждаете, не работает. - person Filipe Gonçalves; 24.01.2016