2016-04-17 1 views
1

書いて、私は自分のコードに問題があります。Linuxのパイプ:機能における不正なファイルディスクリプタを読んで、私はCでの配管について学んだ

私のプログラムは、子プロセスを作成し、親プロセスと子プロセス間のパイプを。私はパイプを介して親から子への単純な文字列を送信しようとしています。しかし、私は機能のエラー・メッセージを取得し、いくつかの理由で書き込み読み:ノー持っ

「エラー読み:不正なファイルディスクリプタを」

を「不正なファイルディスクリプタの書き込みエラー」問題があるという考えは、私はちょうどC.

で配管について学び始めました。ここに私のコードです:

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 

int err(const char* what)//function that writes errors 
{ 
    perror(what); 
    exit(-1); 
} 

int main() 
{ 
    int fdes[2]; //File descriptors for pipe 
    pid_t pid; 
    char string[20] = "Hello World\n";//string that I want to send to childs process 

    int p = pipe(fdes); //Creating pipe 
    if(p < 0) 
     err("pipe error\n"); 

    pid = fork(); //Creating process 
    if(pid < 0) 
     err("fork error\n"); 

    if(pid == 0) //child 
    { 
     p = close(fdes[0]); //Closing unused "write" end of pipe for child 
     if(p < 0) 
      err("close error\n"); 

     char str[20]; //I save the message from parent in this string 
     int p; 
     p = read(fdes[1], str, strlen(str));// Trying to receive the message and save it in str[] 
     if(p < 0) 
      err("read error\n"); 

     printf("Child received: %s\n", str); 
    } 
    else //parent 
    { 
     p = close(fdes[1]); //Closing unused "read" end of pipe for parent 
     if(p<0) 
      err("close error\n"); 

     p = write(fdes[0], string, strlen(string)); //Trying to send the message to child process 
     if(p < 0) 
      err("write error\n"); 

     printf("Parent sent: %s\n", string); 


    } 
    return 0; 
} 
+1

注: 'p = read(fdes [1]、str、strlen(str));'あなたは初期化されていないchar配列に対してstrlen()を呼び出しています。 'p = read(fdes [1]、str、sizeof str);'ここ、または単に '20' – wildplasser

答えて

2

あなたは間違ったファイル記述子の読み書きをしています。 pipe man pageから:

pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe.

1

read(2)戻りEBADFあれば「fdが有効なファイルディスクリプタでないか、を読み取るための開かれていません」。同じようにwrite(2)の場合、記述子が書き込み用に開かれていない場合はEBADFとなります。


機能int pipe2(int pipefd[2], int flags);戻り2ファイル記述子がその

  • pipefd[0] refers to the read end of the pipe.
  • pipefd[1] refers to the write end of the pipe.

ようSTDIN_FILENOSTDOUT_FILENOに対応する配列内のファイル記述子について考えてみよう。あなたはreadから(STDIN_FILENOのような)、writeから(STDOUT_FILENOのように)でしょうか。

+0

しかし、** stdin **と** stdout **のフラグを変更すると、 ** printf **など** **は正常に機能しますか? printfの出力を画面に表示しますか? – WKos

+0

また、** dup2 **関数を使用してファイル記述子を変更すると、上記と同じ結果になりますか? – WKos

関連する問題