2017-09-28 20 views
0

現在、私はexeclpされた子プログラムからの入力行を読んでいます。基本的に、子プログラムが正しく実行されない場合、読み込み時にパイピング情報であってはならず、エラーがスローされます。パイプをポーリングした後でもfgetcがまだブロックされています

ファイルディスクリプタをポーリングしようとしましたが、プログラムが正常に実行されたとしても返されました。だから、基本的に私は過去の投票を取得し、fgetcはハングしている/読んで何もないのでブロックして、fgetcも-1を返していません。

読書とポーリング:

char* read_line(int fd) { 
    // fd is a pipe's read end. I know it reads properly. 
    FILE *file = fdopen(fd, "r"); 
    int ret; 
    struct pollfd fdinfo[1]; 
    fdinfo[0].fd = fd; 
    fdinfo[0].events = POLLIN; 
    ret = poll(fdinfo,1, 1000); 
    if (ret < 0) { 
     return "NOPE"; 
    } 
    char* result = malloc(sizeof(char) * 80); 
    memset(result, 0, sizeof(int)); 
    int position = 0; 
    int next = 0; 
    while (1) { 
     next = fgetc(file); //STALLING HERE 
     if (next == '!') { 
       free(result); 
       return "!"; 
     } 
     if (next == EOF || next == '\n') { 
      result[position] = '\0'; 
      return result; 
     } else { 
      result[position++] = (char)next; 
     } 
    } 
} 
+0

fdinfo [0] .fd = 2; 'fdinfo [0] .fd = fd;'にする必要がありますか? –

+0

これは変更しても、同じ問題が発生しているはずです。それを指摘してくれてありがとう:) – lighthou

答えて

0

あなたが適切poll()によってあなたに提供された情報を確認していません。 poll()が-1を返すことによってエラーを報告するケースを検出しますが、そうでないと、読み取ることができるデータがあることが保証されません。負の戻り値は、poll()がそのジョブを実行できなかったことを示します。ポーリングされたファイル記述子の状態については教えてくれません。

最初に、poll()はタイムアウトすると0を返します。その場合、あなたのコードは先に進んで、ファイル記述子からの読み込みを試みます。戻り値がpoll()からfgetc()になるまでデータが到着しない限りブロックされます。

poll()は、対応するreventビットのうちの1つ以上を設定し、そのFDでイベントを報告することによって(指定された数を返すことによって)、指定されたファイル記述子に問題を通知します。条件が真である場合、具体的に、

poll()は、アプリケーションがイベント

に対応するビットを設定しなかった場合でも 、reventsがPOLLHUP、POLLERRとPOLLNVALフラグをセット

正の[戻り値]は、pollfd構造体[...]の合計数を表し、revents mem berはゼロではない

POSIX 1003.1-2008;強調表示が追加されました)

パイプの反対側に書き込む子プロセスがクラッシュすると、POLLHUPイベントがよく表示されることがあります。あなたのプログラムがファイル記述子の取り扱いをある方法でねじ止めするとPOLLNVALイベントが発生する可能性があります.I/Oエラーの可能性を常に考慮する必要があります。poll()はPOLLERRイベントとして通知します。

したがって、ブロッキングを回避するには、poll()が1を返し、ファイル上のイベントの中でPOLLINに信号を送るときにのみ、パイプからの読み込みを試みる必要があります。あなたはPOLLERRまたはPOLLHUPと一緒にそれを見るかもしれません。 POLLERRが存在する場合は中止することをお勧めしますが、POLLHUPは、パイプの書き込み終了がプロセスで開かれなくなっても、読み込めるようになる可能性のあるデータを無効にしない場合には、付随するPOLLINによって通知される)。

関連する問題