0

以下のコードはread()、シグナルによる中断が原因で関数が失敗した場合に関数を再起動します。はread()、中断された場所から読み取りを再開します。read()文字を読み取る直前に が中断された場合EOF、読み取ったバイト数は何を返しますか?

int r_read(int fd, void *buf, int size)
{
   while((retval=read(fd,buf,size))==-1 && errno ==EINTR);
   return retval;
}  

よろしく。

4

3 に答える 3

3

これが、割り込みの問題を回避するために、読み取られたバイト数を合計として保持する必要がある理由です。また、ノンブロッキング I/O にも役立ちます。

{
    int ret = 0, nread;
    char *nbuf = (char *) buf;

    while ((nread = read(fd, nbuf, size)) != 0)
    {
        if (nread > 0)
            ret += nread, nbuf += nread, size -= nread;
        elif (errno != EINTR)
            break;
    }

    return ret;
}
于 2012-11-04T12:32:48.793 に答える
2

の場合は、ページに従ってデータを読み取る前に中断されたerrno == EINTRことを意味します。つまり、私の読書から、ストリーム内のデータに関する限り、with ステータスが発生しなかったようです。したがって、バイトを失うことを心配することなく、単純に再試行できるようです。これは少し意外で、実際にテストしたことはありませんが、マニュアルにはそう書かれています。readmanreadEINTR

manページの実際のテキストは次のとおりです。

EINTR データが読み取られる前にシグナルによって呼び出しが中断されました。signal(7) を参照してください。

編集:これをテストしたところ、読み取りを中断したEINTR場合、何かが読み取られる前に読み取りが中断された場合にのみ返されることがわかりました。それ以外の場合は、要求されたバイト数よりも少ない読み取りで、正常に返されます。したがって、必要なバイト数を取得するには、他の回答が示すように、再起動するものが必要になります。

于 2012-11-04T12:31:28.207 に答える
0

そのような「EOF文字」はありません。0バイトの読み取りとして示されるファイルの終わりの状態があります。EINTR エラーはread、何かが起こるのを待っている間に が中断された場合にのみ設定されます。つまり、基礎となるリソースがデータを生成する前です。

EOF は通常、read待機を停止して値を返すため、read中断することはできず、中断された場合は、持っているもの (EOF インジケーター) を返すだけです。EOF を待っreadている間に (基礎となるリソースによってアナウンスされる前に)が中断された場合、もちろん -1 を返し、EINTR を設定します。

于 2012-11-04T15:20:29.097 に答える