Возникли проблемы с трубой, вилкой, dup2 - PullRequest
1 голос
/ 28 января 2012

Я использую pipe, fork, dup2 для реализации «ls | больше »или« ls | сортировать »и т. д. Я просто не могу понять проблему здесь. Когда я запускаю свою программу, я получаю эту ошибку:

./a.out  
Missing filename ("less --help" for help)

Почему я получаю "меньше" ??

Что не так с этим кодом? Если я снова изменю «больше» на «ls», это будет работать нормально. Я имею в виду, это как делать ls | левая сторона

#define STDIN 0
#define STDOUT 1

int main()
{
   int fd[2];
   int pid;
   char *lschar[20]={"ls",NULL};
   char *morechar[20]={"more",NULL};
   pid = fork();
   if (pid == 0) {
   /* child */
     int cpid;
     cpid = fork();
     if(cpid == 0) {
       //printf("\n in ls \n");
       pipe(fd);
       dup2(fd[1], STDOUT);
       close(fd[0]);
       close (fd[1]);
       execvp("ls",lschar);
     } else if(cpid>0) {
       waitpid(cpid, NULL,0);
       dup2(fd[0],STDIN);
       close(fd[0]);
       close(fd[1]);
       execvp("more", morechar);
     }
   } else if (pid > 0) {
     /* Parent */
     waitpid(pid, NULL,0);
   }
   return 0;
}

Ценю вашу помощь.

1 Ответ

6 голосов
/ 28 января 2012

Ваша основная проблема заключается в том, что вы сделали pipe() звонок. Вы должны назвать это до вас fork():

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

#define STDIN 0
#define STDOUT 1

int main()
{
  int fd[2];
  int pid;
  char *lschar[20]={"ls",NULL};
  char *morechar[20]={"more", NULL};
  pid = fork();
  if (pid == 0) {
    /* child */
    int cpid;
    pipe(fd);
    cpid = fork();
    if(cpid == 0) {
      //printf("\n in ls \n");
      dup2(fd[1], STDOUT);
      close(fd[0]);
      close (fd[1]);
      execvp("ls",lschar);
    } else if(cpid>0) {
      dup2(fd[0],STDIN);
      close(fd[0]);
      close(fd[1]);
      execvp("more", morechar);
    }
  } else if (pid > 0) {
    /* Parent */
    waitpid(pid, NULL,0);
  }
  return 0;
}

В противном случае, процесс more не имеет правильных файловых дескрипторов. Кроме того, waitpid () в вашем дополнительном процессе является проблематичным и ненужным (more будет ожидать ввода самостоятельно). Если бы у ls был особенно длинный вывод, канал мог бы быть заполнен, в результате чего ls блокировал свои записи. В результате тупик, и он ждет вечно. Следовательно, я также удалил оскорбительный вызов waitpid().

Кроме того, если вы практикуете проверку возвращаемых значений таких функций, как pipe() и dup2(), эту ошибку было бы намного легче найти - вы бы увидели, что ваш dup2() не работает. 1014 *

...