2017-08-30 5 views
0

私はfifoパイプを使ってお互いに話す2つのプログラムを書こうとしています。 例here(セクション5.2)を使用しましたが、mknodをmkfifoに変更してfgetsに変更しようとしました。 これは、(FIFOに書き込み、一つのプログラムの)コードです:mkfifoは2つのプロセスがお互いに話すようにします

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <errno.h> 
#include <sys/types.h> /*mkfifo, open */ 
#include <sys/wait.h> 
#include <sys/stat.h> /* mkfifo, open */ 
#include <fcntl.h> /*open */ 

#define FIFO_PATH "/home/hana/Desktop" 
#define BUFFER_SIZE 300 



int main() 
{ 
    char buffer[BUFFER_SIZE]; 
    int fd; 
    int wStatus; 

    mkfifo(FIFO_PATH, 666); 
    printf("waiting for readers\n"); 
    fd = open(FIFO_PATH, O_RDWR); 

    while (fgets(buffer, BUFFER_SIZE, fd), !feof(stdin)) 
    { 
     if ((wStatus = write(fd, buffer, strlen(buffer))) == -1) 
      perror("write"); 
     else 
      printf("speak: wrote %d bytes\n", wStatus); 
    } 

    return 0; 
} 

私は、コンパイル・エラーが発生します:関数fgetsの引数渡し3は、整数からポインタになります。 したがって、fgetsはファイル記述子ではなくFILE *を想定しています。 どうすればよいですか? fgetsが動作するように何かを変更しますか?別の機能を使用しますか?

gcc(ansi、pedantic)でコンパイルしています。

おかげ

答えて

0

mkfifo()だけで、ファイルシステム内の特殊なノードを作成します。そしてあなたは自由にそれを開くことができます。実際には、POSIXの "バッファされていない" I/O:open()/write()/read()または標準のバッファされたI/O:fopen()/fread()/fwrite()という2つの選択肢があります。最初のファミリはファイル記述子で動作し、2番目のファミリはファイルストリーム(FILE)を使用します。これらのAPIは自由に組み合わせることはできません。ちょうど1つを選択し、それに固執する。 標準I/Oライブラリは、低レベルのバッファされていないI/Oと比較して、いくつかの有用な追加機能を提供します。あなたが使用しようとしているfgets()のように。代わりにプレーンなファイルディスクリプタのFILE*を使用します

FILE* stream = fopen(FIFO_PATH, "r+"); 

したがってプログラム:このような状況では標準ストリームを使用してopen()を交換するのが妥当だろう。また、write()fwrite()に変更する必要があります。書き込まれたデータがFIFOに渡されることを保証するために、すぐにfflush()が続きます。

P.S.必要ならば、標準FILE*open()(または何か他のもの)によって返された低レベルの記述子を「ラップする」ことが可能です。 fdopen()を参照してください。しかし、それはfopen()で開くことができない特別なファイルオブジェクトで標準I/O APIを使用する回避策に非常に似ています。

1

whjmからの答えはあなたのエラーの原因の診断ですが、私はあなたがおそらくそれはあなたがすぐにその後、パイプから読み込むとなり意味をなさない

fgets(buffer, BUFFER_SIZE, stdin) 
//       ^^^^^ 

を意味だと思います同じことをパイプに書き戻します。また、stdinから読むことがない場合、feof(stdin)は決して真実ではありません。関数fgetsでも

は、単にNULLという結果をチェックして、ループの外で、EOFのためにチェックします:

while (fgets(...) != NULL) 
{ 
    ... 
} 
if (!feof(stdin)) 
{ 
    // error handling 
} 
+0

OPはコンパイルエラーと 'FILE * 'の取得方法についてしか聞いていないので、私は実際にコードを読んでいませんでした。 :) – pynexj

+0

@whjm私はあなたの答えが間違っていたことを暗示していません。実際にあなたの票は私のものです。 – JeremyP

+0

私も件名を変更し、タグ 'ipc'と' mkinfo'を削除しました。ちょうど転がった。 :) – pynexj

関連する問題