Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_all bug

名前

       readv, writev, preadv, pwritev - 複数のバッファへの読み書きを行なう

書式

       #include <sys/uio.h>

       ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

       ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

       ssize_t preadv(int fd, const struct iovec *iov, int iovcnt,
                      off_t offset);

       ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt,
                       off_t offset);

   glibc 向けの機能検査マクロの要件 (feature_test_macros(7)  参照):

       preadv(), pwritev(): _BSD_SOURCE

説明

       readv() システムコールは、ファイルディスクリプタ fd に関連付けられた ファイルから、 iovcnt 個のバッファ分
       のデータを読み込み、 iov で指定 されたバッファに格納する ("scatter input";「ばらまき入力」)。

       writev() システムコールは、 iov  で指定されたバッファから最大  iovcnt  個のバッファ分のデータを取り出し、
       ファイルディスクリプタ fd に関連付けら れたファイルに書き込む ("gather output";「かき集め出力」)。

       ポインタ  ioviovec 構造体の配列へのポインタである。 iovec 構造体は <sys/uio.h> で以下のように定義され
       ている:

           struct iovec {
               void  *iov_base;    /* Starting address */
               size_t iov_len;     /* Number of bytes to transfer */
           };

       readv() システムコールは、複数のバッファにデータを読み込む点を除いて read(2) と全く同様の動作を行う。

       writev() システムコールは、複数のバッファのデータを書き出す点以外は write(2) と全く同様の動作を行う。

       バッファは配列の順序で処理される。これは、 readv()  が iov[0]  が完全に一杯になるまでデータを詰めてから、
       iov[1]  などに進むことを意味する  (データが十分ない場合は、 iov が指すバッファのいずれも一杯にならない)。
       同様に、 writev()  は iov[0] の内容を全部書き出してから iov[1] などに進む。

       readv()  と writev()  によるデータ転送は atomic に行われる。つまり、 writev()  によるデータ書き込みは一つ
       のブロックとして行われ、他のプロセスの write による書き込みと混ざり合うことはない (例外に関しては pipe(7)
       を参照のこと)。同様に、 readv()  はファイルから連続するデータブロックが読み出すことが保証され、  同じファ
       イル記述 (file description; open(2)  参照) を参照するファイルディスクリプタを持つ他のスレッドやプロセスが
       実行した read 操作の影響を受けることはない。

   preadv()  pwritev()
       preadv() システムコールは readv() と preadv(2) の機能を 組み合わせたものである。 readv() と同じ処理を実行
       するが、  4  番目の引き数  offset が追加されており、 この引き数は入力操作を行うファイルオフセットを指定す
       る。

       pwritev() システムコールは writev() と pwrite(2) の機能を 組み合わせたものである。 writev()  と同じ処理を
       実行するが、  4 番目の引き数 offset が追加されており、 この引き数は出力操作を行うファイルオフセットを指定
       する。

       これらのシステムコールで、ファイルオフセットは変更されない。 fd が参照するファイルは seek  可能でなければ
       ならない。

返り値

       成功した場合、 readv() と preadv は読み込んだバイト数を返し、 writev() と pwritev()は書き込んだバイト数を
       返す。 エラーの場合 -1 を返し、errno を適切に設定する。

エラー

       read(2)  や write(2)  と同じエラーが定義されている。 さらに、 preadv() と pwritev() は lseek(2)  と同じ理
       由でも失敗する。 また、追加で以下のエラーが定義されている:

       EINVAL iov_len  の合計が ssize_t の範囲をオーバーフローした。もしくは、 ベクタ数 iovcnt が 0 より小さいか
              許可された最大値よりも大きかった。

バージョン

       preadv() と pwritev() は Linux 2.6.30 で初めて登場した。 ライブラリによるサポートは glibc 2.10 で追加され
       た。

準拠

       readv(),  writev(): 4.4BSD (これらのシステムコールは 4.2BSD で最初に現われた)、POSIX.1-2001。 Linux libc5
       では、 iovcnt 引き数の型として size_t を、 返り値の型として int を使用していた。

       preadv(), pwritev(): 非標準だが、最近の BSD にも存在する。

注意

   Linux での注意
       POSIX.1-2001 では、 iov で渡すことができる要素数に上限を設ける実装が認められている。 実装は、  <limits.h>IOV_MAX  を定義することや、実行時に sysconf(_SC_IOV_MAX) の返り値経由で、この上限を広告することができ
       る。 Linux では、この仕組みにより広告される上限は 1024 であり、  この値はカーネルでの上限そのものである。
       一方で、glibc のラッパー関数は、その関数の内部で呼ばれるカーネル システムコールがこの上限を超過して失敗し
       たことを検出すると、 追加の動作をする。 readv()  の場合、ラッパー関数は iov  で指定された全ての要素を格納
       できる大きさの一時バッファを割り当て、 read(2)  を呼び出す際にそのバッファを渡し、 そのバッファのデータを
       iov の各要素の iov_base フィールドが指定する場所にコピーしてから、 そのバッファを解放する。  writev()  の
       ラッパー関数も、同じように一時バッファを使って write(2)  を呼び出す。

バグ

       ファイルディスクリプタに対する操作を行う  readv() や writev() と、 標準入出力ライブラリの関数をごちゃまぜ
       にして呼ぶのはお薦めしない。 どんな結果になるかは定義されておらず、おそらく期待する結果は  得られないだろ
       う。

       以下のサンプルコードは writev()  の使用方法を示すものである。

           char *str0 = "hello ";
           char *str1 = "world\n";
           struct iovec iov[2];
           ssize_t nwritten;

           iov[0].iov_base = str0;
           iov[0].iov_len = strlen(str0);
           iov[1].iov_base = str1;
           iov[1].iov_len = strlen(str1);

           nwritten = writev(STDOUT_FILENO, iov, 2);

関連項目

       pread(2), read(2), write(2)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 3.54 の一部 である。プロジェクトの説明とバグ報告
       に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。