2016-08-29 3 views
0

Я пытаюсь реализовать оболочку simpel c, которая будет конвейерное произвольное количество команд. Вот соответствующий цикл:pipe: Плохой дескриптор файла

int status; 
int i,j,inputFile,outputFile,pid; 
int pipeNum = info->pipeNum; 

struct commandType *command; 

int pipes[pipeNum * 2]; 
for(i=0;i<pipeNum;i++){ 
    pipe(pipes+2*i); 
    printf("PIPE NUMBER %d CREATED\n", i+1); 
} 
for(j=0;j<=pipeNum;j++){ 
    if((pid=fork()) ==0){ 
    if(j!=0){ 
     if(dup2(pipes[(j-1)*2],STDIN_FILENO)<0){ 
     perror("pipe"); 
     exit(2); 
     } 
    } 
    if(j!=pipeNum){ 
     if(dup2(pipes[2*j+1],STDOUT_FILENO)<0){ 
     perror("pipe"); 
     exit(2); 
     } 
    } 
    if(j==0 && info->boolInfile==1){ 
     if((inputFile = open(info->inFile,O_RDONLY))<0){ 
    perror("file"); 
    exit(2); 
     } 
     if(dup2(inputFile,STDIN_FILENO)<0){ 
     perror("dup2"); 
     exit(2); 
     } 
    } 
    if(j==pipeNum && info->boolOutfile){ 
     if((outputFile = open(info->outFile,O_WRONLY | O_CREAT | O_TRUNC, 666)<0)){ 
    perror("file"); 
    exit(2); 
     } 

     if(dup2(outputFile,STDOUT_FILENO)<0){ 
     perror("dup2"); 
     exit(2); 
     } 
    } 
    for(i=0;i<pipeNum*2;i++){ 
     close(pipes[i]); 
     } 
    command=&info->CommArray[j]; 
    execvp(command->VarList[0],command->VarList); 
    perror("Bad command"); 
    } 
    for(i=0;i<pipeNum*2;i++){ 
    close(pipes[i]); 
    } 
    for(i=0;i<pipeNum+1;i++){ 
    wait(&status); 
    } 
} 

Но когда я пытаюсь запустить команду

cat file.txt | wc 

Я получаю следующее сообщение об ошибке:

pipe: Bad file descriptor. 

Видит кто-нибудь изъян в моем коде Вот? Я не могу понять, чтобы спасти свою жизнь.

Я добавил несколько операторов строки печати, и я получаю дескриптор плохого файла для каждого отдельного канала. тьфу.

+0

Использование 'PError ("трубы");' после звонков 'dup2()' вводит в заблуждение. Для всех практических целей вы не можете получить EBADF из ['pipe()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html), но вы, безусловно, можете использовать ['dup2 () '] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html). Пожалуйста исправьте! –

+0

Когда вы переходите к 'j == pipeNum-1' в последней, но одной итерации цикла, вы получаете доступ к элементам массива' pipe', который вы никогда не инициализировали ('if (dup2 (pipe [2 * j + 1 ], STDOUT_FILENO) <0) {'например). –

+0

Да, но perror («pipe») действительно для моего bennefit, так как он говорит мне, где я напортачиваю ... – nbk

ответ

0

Плохие строки кода находятся в самом конце цикла for. Вместо

} 
    for(i=0;i<pipeNum*2;i++){ 
    close(pipes[i]); 
    } 
    for(i=0;i<pipeNum+1;i++){ 
    wait(&status); 
    } 
} 

я должен

}  
} 
for(i=0;i<pipeNum*2;i++){ 
    close(pipes[i]); 
} 
for(i=0;i<pipeNum+1;i++){ 
    wait(&status); 
} 
+0

Это проблема. Но как это приводит к наблюдаемым симптомам, когда вызов 'dup2' терпит неудачу? – kaylum

Смежные вопросы