Форкинг с трубами - PullRequest
       13

Форкинг с трубами

1 голос
/ 08 апреля 2010

Я попытался выполнить fork () и конвейеризацию в main, и это прекрасно работает, но когда я по какой-то причине пытаюсь реализовать его в функции, я не получаю никакого вывода, это мой код:

void cmd(int **pipefd,int count,int type, int last);    

int main(int argc, char *argv[]) {
int pipefd[3][2];
int i, total_cmds = 3,count = 0;
int in = 1;

for(i = 0; i < total_cmds;i++){
 pipe(pipefd[count++]);
 cmd(pipefd,count,i,0);    
}

 /*Last Command*/
 cmd(pipefd,count,i,1);    

exit(EXIT_SUCCESS);
}

void cmd(int **pipefd,int count,int type, int last){    
    int child_pid,i,i2;

     if ((child_pid = fork()) == 0) {

            if(count == 1){
               dup2(pipefd[count-1][1],1); /*first command*/
            }
            else if(last!=1){
               dup2(pipefd[count - 2][0],0); /*middle commands*/
               dup2(pipefd[count - 1][1],1);
            }
            else if(last == 1){
               dup2(pipefd[count - 1][0],0); /*last command*/
            }


            for(i = 0; i < count;i++){/*close pipes*/
            for(i2 = 0; i2 < 2;i2++){
               close(pipefd[i][i2]);
            }}



            if(type == 0){
                execlp("ls","ls","-al",NULL);
            }
            else if(type == 1){
                execlp("grep","grep",".bak",NULL);
            }
            else if(type==2){
                               execl("/usr/bin/wc","wc",NULL);
            }
            else if(type ==3){
                         execl("/usr/bin/wc","wc","-l",NULL);
           }
            perror("exec");
            exit(EXIT_FAILURE);
    }
    else if (child_pid < 0) {
            perror("fork");
            exit(EXIT_FAILURE);
    }
}

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

Редактировать: я исправил проблему, но у меня есть дочерние процессы, в каком случае лучше всего ждать ребенка, в то время как (wait (NULL)! = - 1); но это висит

1 Ответ

2 голосов
/ 08 апреля 2010

Проблема в том, что pipefd - это не int**, а int[3][2], поэтому, когда вы передаете его в cmd, вы получаете мусор.Ваш компилятор должен предупреждать вас при каждом вызове cmd(), например, примерно так:

warning: passing argument 1 of 'cmd' from incompatible pointer type

Если нет, увеличьте уровень предупреждения.

Верно, что массивы распадаются на указатели на их первые элементы, поэтому вы можете передать одномерный массив функции, ожидающей указатель, но это верно только для первого измерения массивов .В частности, двумерный массив не превращается в указатель на указатель.Распадается только на первом уровне, поэтому pipefd может распадаться на тип int (*)[2], который читается как "указатель на массив 2 из int"

Итак, правильный способ записи cmd это:

void cmd(int (*pipefd)[2],int count,int type, int last)
...