Циклы трубы с exec в C

Я пытался реализовать конвейер в своем коде, где он принимает строку, разделяет ее на несколько команд (результат - аргументы), выполняет (execvp) и записывает/читает результаты с помощью конвейера, но я застрял на последнем шаге.

Чтобы решить эту проблему, я попытался использовать цикл for, где 1. первый элемент записывает, 2. средние читают/записывают, 3. последний читает.

Я попытался решить эту проблему, используя 2 пары файловых дескрипторов для чтения/записи.

Код компилируется, но не работает. Я предполагаю, что я неправильно использую дескрипторы close и file.

Функция:

int exec_multi(char*** args, int count)
{
    int pipefd1[2];
    int pipefd2[2];
    int pid;
    int i;
    char ** arguments;
    for (i = 0; i < count; i++)
    {
       arguments = args[i];
       if (i==0)
       {
          printf("Write %i\n", i);
          if (pipe(pipefd1) == -1) {
            perror("Shell: Piping error\n");
            exit(1);
          }

          if ((pid = fork()) == -1) {
            perror("Shell: Forking error\n");
            exit(1);
          } else if (pid == 0) {
            printf("first shit\n");
            dup2(pipefd1[1], STDOUT_FILENO);
            close(pipefd1[0]);
            close(pipefd1[1]);
            execvp(arguments[0], arguments);
            perror("Shell: Executing error\n");
            _exit(1);
          }
       }
       else if (i==(count-1))
       {
           printf("Read %i\n", i);
            if ((pid = fork()) == -1) {
                perror("Shell: Forking error\n");
                exit(1);
            } else if (pid == 0) {
                printf("last sh\n");
                dup2(pipefd1[0], STDIN_FILENO);
                close(pipefd1[0]);
                close(pipefd1[1]);
                execvp(arguments[0], arguments);
                perror("Shell: Executing error\n");
                _exit(1);
            }
       }
       else
       {
           printf("Read & write %i\n", i);
            if (pipe(pipefd2) == -1)
            {
                perror("Shell: Piping error\n");
                exit(1);
            }
            if ((pid = fork()) == -1) {
                perror("Shell: Forking error\n");
                exit(1);
            } else if (pid == 0) {
                dup2(pipefd1[0], STDIN_FILENO);
                dup2(pipefd2[1], STDOUT_FILENO);
                close(pipefd1[0]);
                close(pipefd1[1]);
                pipefd1[0] = pipefd2[0];
                pipefd1[1] = pipefd2[1];
                close(pipefd2[0]);
                close(pipefd2[1]);
                execvp(arguments[0], arguments);
                perror("Shell: Executing error\n");
                _exit(1);
            }
       }
    }

    return 1;
}

person DevGambit    schedule 30.10.2017    source источник
comment
Без MCVE будет очень сложно понять, что не так (минимальный воспроизводимый пример). Вероятно, поэтому вы еще не получили никаких ответов.   -  person Jonathan Leffler    schedule 31.10.2017
comment
Нашел это с помощью Google, который может помочь: Как захватить stdin, stdout и stderr дочерней программы!   -  person Scheff's Cat    schedule 31.10.2017
comment
Мой поисковый запрос в Google был вилкой stdout stdin. 2-й ответ: SO: C Pipe to STDIN другой программы   -  person Scheff's Cat    schedule 31.10.2017