read() - ファイルまたはソケットからの読み取り

標準

標準/拡張機能 C/C++ 依存項目

POSIX.1
XPG4
XPG4.2
Single UNIX Specification、バージョン 3

両方  

形式

#define_POSIX_SOURCE
#include <unistd.h>

ssize_t read(int fs, void *buf, size_t N);
X/Open
#define _XOPEN_SOURCE_EXTENDED 1
#include <unistd.h>

ssize_t read(int fs, void *buf, ssize_t N);
バークレー・ソケット
#define _OE_SOCKETS
#include <unistd.h>

ssize_t read(int socket, void *buf, ssize_t N);

機能説明

read() 関数は、ファイル記述子 fs で表されるファイルか ら、buf で表されるメモリー域に、入力の N バイトを 読み込みます。read() が正常に実行されると、ファイルのアクセス時刻が更新さ れます。

fs が、通常ファイルまたはプロセスが検索できるその他の タイプのファイルを参照する場合には、read() により、fs と 関連したファイル・オフセットから読み取りが開始されます。正常に実行された場合、read() は、読み取ったバイト数によってファイル・ オフセットを変更します。N は、INT_MAX (limits.h ヘッダー・ファイルで定義されている) より大きくはなりません。

fs が、プロセスがシークできないファイルを参照する場合には、read() は、現在位置から読み取りを開始します。このようなファイルと関連したファイル・オフセットはありません。

fs がソケットを参照している場合には、read() は、フラグを設定しない recv() と同等です。
パラメーター
説明
fs
ファイルまたはソケットの記述子。
buf
データを受け取るバッファーへのポインター。
N
buf パラメーターが指すバッファーの 長さ (バイト単位)。

ソケットの場合の動作: read() 呼び出しは、記述子 fs を用いてソケット上のデータを 読み取り、それがバッファーに保管されます。 read() 呼び出しはすべて、接続されたソケットにのみ適用されます。この呼び出しは、最大 N バイトまでのデータを戻します。使用可能なバイトが要求したバイトより少ないと、呼び出しは、現在使用可能な 数を戻します。ソケット fs のデータが使用できず、さらにソケットが ブロック・モードになっている場合は、データが到着するまで、read() 呼び出しは呼び出し元をブロックします。データが使用できず、さらにソケットがブロック解除モードになっ ている場合、read() は -1 を戻します。また、エラー・コードが EWOULDBLOCK に設定されます。非ブロッキング・モードの設定方法の説明については、ioctl() - 装置の制御または fcntl() - オープン・ファイル記述子の制御を参照してください。

データグラム・ソケットの場合には、このデータグラムの大きさが指定のバッファー に収まるならば、この呼び出しは、送信されたデータグラム全体を戻します。余分なデータグラム・データは廃棄されます。ストリーム・ソケットは、データを分離する境界のない情報ストリームのように動作します。例えば、アプリケーション A および B がストリーム・ソケットと接続され、アプリケーション A が 1000 バイトを送信した場合には、この関数のそれぞれの 呼び出しは、1 バイト、または 10 バイト、あるいは 1000 バイト全体を戻すこと ができます。したがって、ストリーム・ソケットを使用するアプリケーションは、この呼び出しをループに入れて、すべてのデータを受信するまで、この関数を呼び出す必要があります。

ストリームの動作: STREAMS ファイルからの read() は、異なる 3 つのモード (バイト・ ストリーム・モード、メッセージ廃棄以外のモード、およびメッセージ廃棄モード) で、データを読み取ることができます。 デフォルトはバイト・ストリーム・モードです。これは I_SRDOPT ioctl() 要求を使用して変更したり、I_GRDOPT ioctl() でテストすることができます。バイト・ストリーム・モードでは、要求されたバイト数と同じバイト数が転送される まで、または検索するデータがなくなるまで、read() は STREAM からデータを検索 します。バイト・ストリーム・モードでは、メッセージ境界が無視されます。

STREAMS メッセージ非廃棄モードでは、要求されたバイト数と同じバイト数が転送されるまで、またはメッセージ境界に達するまで、read() はデータを検索します。read() で検索されたのが、メッセージ中のデータのすべてではなかった場合には、残りのデータは STREAM に残され、次の read() 呼び出しで検索できます。また、メッセージ廃棄モードでも、要求されたバイト数と同じバイト数が転送されるまで、あるいはメッセージ境界に達するまで、データを検索します。ただし、read() が戻った後にメッセージ中に残っている、読み取られていないデータは廃棄され、以降の read()、readv()、または getmsg() 呼び出しでは使用できません。

read() によるゼロ・バイト STREAMS メッセージの処理方法は、設定中の現行読み取りモードによって決まります。バイト・ストリーム・モードでは、N バイトを読み取るまで、あるいはゼロ・バイトのメッセージ・ブロックが見つかるまで、read() はデータを受け入れます。この場合、read() 関数は、読み取りバイト数を戻し、ゼロ・バイト・メッセージが STREAM に入れられ、次の read()、readv()、または getmsg() によって検索されます。メッセージ廃棄以外のモードまたはメッセージ廃棄モードでは、ゼロ・バイト・ メッセージが 0 を戻し、このメッセージは STREAM から除去されます。ゼロ・バイト・メッセージが STREAM の最初のメッセージとして読み取られる 際には、読み取りモードとは関係なく、このメッセージは STREAM から除去され、0 が戻されます。

STREAM ファイルからの read() は、メッセージの優先順位のバンドにかかわらず、STREAM ヘッド読み取りキューの前のメッセージ中にデータを戻します。

デフォルトによって、STREAM は制御正常モードになっており、このモードでは、STREAM ファイルからの read() が処理できるのは、データ・パートは含むが、制御パートを含まないメッセージのみです。制御パートを含むメッセージが STREAM ヘッドに現れると、read() は 失敗します。このデフォルト・アクションは、I_SRDOPT ioctl() コマンドを使用 して、STREAM を制御データ・モードまたは制御廃棄モードのどちらかにすること によって変更できます。制御データ・モードでは、任意の制御パートがデータに変換され、同一の メッセージにもとからあるデータ・パートのいずれかを渡す前に、read() が変換します。制御廃棄モードでは、read() は、メッセージ制御パートを廃棄しますが、メッセージのすべてのデータ・パートをプロセスに戻します。

さらに、STREAM ヘッドで呼び出しの前に非同期のエラーが処理されていた場合は、read() および readv() は失敗します。この場合には、errno の値は、read() または readv() の結果を反映しませんが、前に発生したエラーは反映します。STREAM の読み取り中にハングアップが発生した場合は、read() は STREAM ヘッド読み取りキューが空になるまで、通常どおり操作を続行します。その後で、0 を戻します。

z/OS® UNIX の大規模ファイルのサポート: AMODE 64 C/C++ アプリケーションの場合は、z/OS UNIX の大規模ファイルが自動的にサポートされます。AMODE 31 C/C++ アプリケーションは、オプション LANGLVL(LONGLONG) を指定してコンパイルされなければなりません。また、ヘッダーがインクルードされる前に _LARGE_FILES フィーチャー・テスト・マクロを定義して、2 GB のサイズより大きい z/OS UNIX ファイルをこの関数が操作できるようにしなければなりません。ファイル・サイズとオフセット・フィールドは、63 ビットの幅に拡張されます。したがって、_LARGE_FILES フィーチャー・テスト・マクロの定義も行うには、ファイルを操作する他のいずれかの関数が必要です。

戻り値

正常に実行された場合、read() は、実際に読み取られて buf に入れられたバイト数を戻します。この数は N より小さいか等しくなります。N より小さいのは以下の場合のみです。
  • read() が、要求されたバイト数を読み取る前に、ファイルの最後に達 した。
  • read() にシグナルが割り込んだ。
  • POSIX C プログラムに限り、ファイルはパイプ、FIFO 特殊ファイル、または 文字特殊ファイルであり、N バイトより少ないバイト数しか読み取りに即時 に使用できません
  • 物理ファイル・システムがディレクトリーからの単純読み取りをサポートしていない場合、read() は、ディレクトリーに 0 が使用されている場合は、0 を戻します。 ユーザーは、代わりに Opendir() および readdir() を使用する必要があります。
POSIX C プログラムに限り、read() にシグナルが割り込むと、結果は次のいずれかになります。
  • read() がまだデータを読み取っていない場合には、-1 が戻され、errno が EINTR に設定されます。
  • read() が一部のデータを正常に読み取った場合には、割り込まれる前に読み取ったバイト数を戻します。

読み取り操作の開始位置が、ファイルの最後またはそれを超える場合には、read() は 0 を戻します。

POSIX C プログラムでは、read() が空のパイプまたは FIFO 特殊フ ァイルからの読み取りを試みると、以下のいずれかの結果になります。
  • プロセスに、書き込み用にオープンされたパイプがない場合には、read() は、ファイルの終わりを示す 0 を戻します。
  • 一部のプロセスに、書き込み用にオープンされたパイプがあり、O_NONBLOCK が 1 に設定されていると、read() は -1 を戻し、errno は EAGAIN に設定されます。
  • 一部のプロセスに書き込み用にオープンされたパイプがあり、O_NONBLOCK が 0 に設定されていると、一部のデータが書き込まれるか、あるいはパイプを書き込み用にオープンしたパイプをもつその他のすべての プロセスによってパイプがクローズされるまで、read() はブロックさ れます (すなわち、戻りません)。
ブロック以外の読み取り操作をサポートするその他のファイル (例えば、文字特殊 ファイル) には、次のような同様の原則が適用されます。
  • データが使用可能な場合、read() はそのデータを即時に読み取ります。
  • データが使用不可で、O_NONBLOCK が 1 に設定されていると、read() は -1 を戻し、errno が EAGAIN に設定されます。
  • データが使用不可で、O_NONBLOCK が 0 に設定されていると、一部のデータが使用可能になるまで、read() はブロックされます。
以下のような条件がすべて存在するときに、read() によって、シグナル SIGTTIN が送信されます。
  • 制御端末からの読み取りを処理で行おうとしている。
  • プロセスがバックグラウンド・プロセス・グループで実行中である。
  • SIGTTIN シグナルがブロックされていないかまたは無視されない。
  • プロセスのプロセス・グループが孤立していない。

read() が通常ファイルを読み取り中で、まだ書き込まれていないファイルの 一部が見つかった場合 (ただし、ファイルの終わりの前) には、read() は未書き込みバイトの代わりに、0 バイトを buf に入れます。

読み取りたい入力のバイト数が 0 の場合、read() は、その他のどんなアクションも試みずに、単に、0 を戻します。

ストリーム・ソケットでの接続が失敗したが、データは使用できる場合には、read() 関数はデータを読み取り、エラーにはなりませ ん。ストリーム・ソケットでの接続は失敗したが、データが使用できない場合には、read() 関数は、EOF として 0 バイトを戻します。

注: z/OSUNIX サービスは、どのような STREAMS 装置または疑似装置も提 供しません。read() は、fs によって指示された STREAMS ベースのファイルから どのようなデータも読み取ることはできません。これは常に、EBADF に設定された errno と共に、-1 を戻します。EINVAL は、多重化 STREAMS ドライバーがないため、決して設定されることは ありません。詳細は、open() — ファイルのオープンを参照してください。
正常に実行されなかった場合は、read() は -1 を戻し、errno に次のいずれかを設定します。
エラー・コード
説明
EAGAIN
O_NONBLOCK が 1 に設定されるが、データは読み取りに使用できませんでした。
EBADF
fs が、有効なファイルまたはソケット記述子ではあり ません。
ECONNRESET
接続はピアによって強制的にクローズされました。
EFAULT
buf および N パラメーターを使用すると、呼び出し元アドレス・スペースの外側のメモリーへのアクセスを試みる結果になります。
EINTR
read() は、データが使用可能になる前にキャッチされたシグナル によって割り込まれました。
EINVAL
N に、0 より小さい値が含まれているか、または 要求が無効か、サポートされていないか、あるいは fs によって 参照された STREAM またはマルチプレクサーが、マルチプレクサーから (直接または間接に) リンクされたダウンストリームです。
EIO
プロセスがバックグラウンド・プロセス・グループに入っていて、その制御端末から読み取ろうとしています。さらに、この プロセスが SIGTTIN シグナルを無視またはブロックされているか、あるいはプロセスのプロセス・グループが孤立しています。ソケットの場合は、入出力エラーが発生しました。
ENOBUFS
使用可能なシステム・リソースが不十分で、呼び出しを完了させることができません。
ENOTCONN
接続されていない接続指向ソケットに対する受信が試みられました。
EOVERFLOW
ファイルは、通常ファイルであり、ファイルに関連したオフセットの最大値またはそれを超えた値で、読み取りまたは書き込みが試みられました。
ETIMEDOUT
接続の設定中またはアクティブな接続での伝送のタイムアウトのために、接続がタイムアウトになりました。
EWOULDBLOCK
socket は、非ブロック・モードになっているため、データの読み取りはできません。または、SO_RCVTIMEO タイムアウト 値に達したためデータを使用できませんでした。

CELEBR03
/* CELEBR03

   This example opens a file and reads input.

 */
#define _POSIX_SOURCE
#include <fcntl.h>
#include <unistd.h>
#undef _POSIX_SOURCE
#include <stdio.h>

main() {
  int ret, fd;
  char buf[1024];

  system("ls -l / >| ls.output");

  if ((fd = open("ls.output", O_RDONLY)) < 0)
    perror("open() error");
  else {
    while ((ret = read(fd, buf, sizeof(buf)-1)) > 0) {
      buf[ret] = 0x00;
      printf("block read: ¥n<%s>¥n", buf);
    }
    close(fd);
  }

  unlink("ls.output");
}
出力:
block read:
<total 0
drwxr-xr-x   3 USER1    SYS1           0 Apr 16 07:59 bin
drwxr-xr-x   2 USER1    SYS1           0 Apr  6 10:20 dev
drwxr-xr-x   4 USER1    SYS1           0 Apr 16 07:59 etc
drwxr-xr-x   2 USER1    SYS1           0 Apr  6 10:15 lib
drwxrwxrwx   2 USER1    SYS1           0 Apr 16 07:55 tmp
drwxr-xr-x   2 USER1    SYS1           0 Apr  6 10:15 u
drwxr-xr-x   6 USER1    SYS1           0 Apr  6 10:15 usr
>

関連情報