2016-08-29 9 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. 

は、誰もが自分のコードに欠陥を見ないしここに?私は人生を救うためにそれを理解できません。

いくつかの印刷行ステートメントを追加しましたが、1本のパイプごとに不正なファイル記述子を取得しました。 ugh。

+0

を持つ必要があります;' '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'に到達すると、決して初期化しなかった' pipes'配列の要素にアクセスしています( 'if(dup2(pipes [2 * j + 1 ]、STDOUT_FILENO)<0){'など)。 –

+0

ええ、しかし、perror( "パイプ")は、私がどこにいているのかを教えてくれるので、本当に私のベネフィットのためです... – nbk

答えて

0

コードの悪い行は、forループの最後にあります。代わりに

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

の私は `にperror( "パイプ")を使用して

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

それは問題です。しかし、 'dup2'呼び出しが失敗した場合にどのように観察されますか? – kaylum

関連する問題