Subject: How do I check to see if there are characters to be read ... ?
Date: Thu Mar 18 17:16:55 EST 1993

4.2) 実際に文字を読み込まずに読む文字があるかどうか確かめるにはどうすれば よいのでしょうか。

あるバージョンの UNIX には、特定の時点でファイルディスクリプタに読み込 む文字があるかどうかをチェックする方法があります。BSD ではselect(2) が この目的に使えます。また、 FIONREAD ioctl を使うことも出来ます (tty(4) を参照して下さい)。FIONREAD ioctl は読める文字数を返しますが、端末、パ イプ、ソケットにしか使えません。System V Release 3 では、poll(2)が使え ますが、poll はストリームにしか使うことが出来ません。Xenix (と UNIX SysV r3.2 とそれ以降) では、rdchk() システムコールを使うことにより指定 したファイルディスクリプタへの read() 呼び出しが入力待ちでブロックする かどうかを知ることが出来ます。

FILE ポインタを使っている場合、読み込む文字をがあるかどうかをチェック する方法はありません (入力バッファが空でないことを調べるために標準入出 力データ構造体の中身を詮索することは出来ます。しかしながら、入力バッファ が空だった場合、バッファを埋めようとした時に何が起こるかを知る手段がな いため、うまくいかないでしょう)。

nonblocking read (ブロックしない読み込み) を行ないたい場合に次のような コーディングをしようと考え、この質問をする方がたまにいらっしゃいます。

if (fd から文字が読めるならば)
read(fd, buf, sizeof buf);
これは nonblocking read をする時には最良の方法ではありません。その理由 は、テストした瞬間には文字を読み込み可能だったとしても、read を呼び出 した時には読み込みが出来なくなっていることがあり得るからです。 nonblocking read をうまく行なうには、fcntl(2) で F_SETFL を使って、 O_NDELAY フラグ (BSD では FNDELAY とも呼ばれています) を設定するとよい でしょう。古いシステム(Version 7や 4.1BSDなど)には O_NDELAY を持たない ものもあります。このようなシステムで nonblocking read にもっとも近い動 作をさせるには、alarm(2) を使い、読み込み動作にタイムアウトを設定する のが良いでしょう。


UNIX FAQ LIST / Copyright(c)1994,Ted Timar / tmatimar@isgtec.com


Maintainer: あさだ たくや