Итеративная реализация конвейера для Linux в C - PullRequest
0 голосов
/ 29 сентября 2011

Я знаю, что этот вопрос часто задают, но я все еще не совсем понимаю, как решить мою проблему.Я попытался написать код, который обрабатывает ввод командной строки для возможности нескольких каналов.Тем не менее, я неудачен и мой код, хотя выполнение не работает правильно.Ошибка в том, что когда я разветвил детей, я не могу получить следующую команду, к которой идет канал после выполнения самой первой команды.Как перейти к следующей команде в канале, не захватывая неправильные файловые дескрипторы?Вот кусок кода;

      a = 0;
      while (a < cmdnum)
      {
      pid[a] = fork();
      if( pid[a] == 0)
      {
      if( a == 0)
        {

          close(1);
          dup(p1_to_pn[a][1]);
          for( k = 0; k < nump; k++)
            {
              close(p1_to_pn[k][0]);
              close(p1_to_pn[k][1]);
            }  

          args = tokenize(cmd[a]);
          execv(args[0], args);
        }
      else if ( a == (cmdnum-1))
        {

          close(0);
          dup(p1_to_pn[a][0]);
          for( k = 0; k < nump; k++)
            {
              close(p1_to_pn[k][0]);
              close(p1_to_pn[k][1]);
            }
          args = tokenize(cmd[a]);

          i = execv(args[0], args);
        }
      else
        {

          close(0);
          dup(p1_to_pn[a][0]);
          close(1);
          dup(p1_to_pn[a][1]);
          for( k = 0; k < nump; k ++)
            {
              close(p1_to_pn[k][0]);
              close(p1_to_pn[k][1]);
           }
          args = tokenize(cmd[a]);

          execv(args[0], args);
        }
    }
  a++;
}

1 Ответ

1 голос
/ 29 сентября 2011

Ваша ошибка в том, что вам нужно перейти к следующей команде. Запустите их всех.

Вот основная идея для конвейера типа A | B | C

Родительский процесс читает командную строку. Для каждой новой команды она собирается запустить новый процесс и в конечном итоге выполнить его. В родительском процессе уже открыт fd 0,1,2 (STDIN, STDOUT и STDERR.) Когда вы запускаете канал, используйте системные вызовы pipe (2) и dup (2), чтобы создать новый fd; форк следующий процесс.

Все манипуляции с fd происходят в родительском процессе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...