2012-03-27 6 views
1

私は外部プログラムと通信するためにこの関数を書きました。そのようなプログラムはstdinからの入力を受け取り、その出力をstdoutに出力します。 私のコードをこのプログラムと通信させるために、パイプを使ってstdinとstdoutをバッファにリダイレクトします。Cパイプ()は、特定の呼び出し回数後にエラーを返します

int query_oracle(mpz * c,int *t, mpz * m) { 
    int out_pipe[2]; 
    int in_pipe[2]; 
    int saved_stdout; 
    int saved_stdin; 

    // REDIRECT STDIN 
    saved_stdin = dup(STDIN_FILENO);  /* save stdin for later */ 
    pipe(in_pipe);   /* make a pipe */ 
    close(STDIN_FILENO); 
    dup2(in_pipe[0], STDIN_FILENO); /* redirect pipe to stdin */ 
    //write(in_pipe[1], in_buf, strlen(in_buf)); 

    // REDIRECT STDOUT 
    saved_stdout = dup(STDOUT_FILENO); /* save stdout for display later */ 
    if(pipe(out_pipe) != 0) {   /* make a pipe */ 
    exit(1); 
    } 
    dup2(out_pipe[1], STDOUT_FILENO); /* redirect stdout to the pipe */ 
    close(out_pipe[1]); 

    /* Some reads and writes on the pipes occur here 
    * so that the program can communicate with an 
    * external program*/ 

    dup2(saved_stdout, STDOUT_FILENO); /* reconnect stdout */ 
    dup2(saved_stdin, STDIN_FILENO); /* reconnect stdin */ 

    return 0; 
} 

この関数を呼び出すのは204回目ですが、pipe()はエラー(-1)を返します。 それはなぜですか、それを避けるにはどうすればよいですか?おかげで多く

詳細:これはLinux上です。 uname -aの結果は次のようになります。

Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux 
+2

エラー時の値または 'errno'は何を?次の – trojanfoe

+1

'man 3 errno'、' ulimit -n'を実行して、開いているファイル記述子の数を確認してください。 –

+2

さらに、 'strerror(errno)'の値は? –

答えて

0

多くの人からお勧めのように、問題は関数から戻る前にファイル記述子を閉じることを怠っていたため、すぐに使用可能なものから使い果たしました。

ここでは、コードの改訂(作業)バージョン

int query_oracle(mpz * c,int *t, mpz * m) { 
    int out_pipe[2]; 
    int in_pipe[2]; 
    int saved_stdout; 
    int saved_stdin; 

    // REDIRECT STDIN 
    saved_stdin = dup(STDIN_FILENO);  /* save stdin for later */ 
    pipe(in_pipe);   /* make a pipe */ 
    close(STDIN_FILENO); 
    dup2(in_pipe[0], STDIN_FILENO); /* redirect pipe to stdin */ 
    //write(in_pipe[1], in_buf, strlen(in_buf)); 

    // REDIRECT STDOUT 
    saved_stdout = dup(STDOUT_FILENO); /* save stdout for display later */ 
    if(pipe(out_pipe) != 0) {   /* make a pipe */ 
    exit(1); 
    } 
    dup2(out_pipe[1], STDOUT_FILENO); /* redirect stdout to the pipe */ 
    close(out_pipe[1]); 

    /* Some reads and writes on the pipes occur here 
    * so that the program can communicate with an 
    * external program*/ 

    dup2(saved_stdout, STDOUT_FILENO); /* reconnect stdout */ 
    dup2(saved_stdin, STDIN_FILENO); /* reconnect stdin */ 

    /* close all open file descriptors */ 
    close(in_pipe[1]); 
    close(in_pipe[0]); 
    close(out_pipe[1]); 
    close(out_pipe[0]); 
    close(saved_stdin); 
    close(saved_stdout); 

    return 0; 
} 
6

ファイルディスクリプタを実行している可能性があります。リモートプログラムをフォークした後で、プログラム内でin_pipe [1]とout_pipe [0]を閉じていない可能性があります。

+1

そして 'saved_stdout'と' saved_stdin'を4 * 204〜= 1024(fdの可能性の高いもの)にしてみましょう。 – trojanfoe

+1

これは 'EMFILE'を与えますが、OPは' EPERM'を得ているようです。 –

+0

@larsmans私は彼がいるとは思わない。私は改訂されたコードを見たいと思います。 – trojanfoe

関連する問題