readv - システムコールの説明 - Linux コマンド集 一覧表
名前
readv, writev - 複数のバッファへの読み書きを行なう
書式
#include <sys/uio.h>
ssize_t readv(int fd, const struct iovec *vector, int count);
ssize_t writev(int fd, const struct iovec *vector, int count);
説明
readv ()関数は、ファイル・ディスクリプタ fd に関連付けられたファイルから count ブロックのデータを読み込み、 vector で指定された複数のバッファに格納する。
writev ()関数は、 vector で指定されたバッファから最大 count ブロックのデータを取り出し、ファイル・ディスクリプタに関連付けられた ファイルに書き込む。
ポインタ vector は struct iovec へのポインタである。 struct iovec は <sys/uio.h> で以下のように定義されている:
struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes */ };
バッファは指定された順序で処理される。
readv ()関数は、複数のバッファにデータを読み込む点を除いて read (2) と全く同様の動作を行う。
writev ()関数は、複数のバッファのデータを書き出す点以外は write (2) と全く同様の動作を行う。
返り値
成功した場合、 readv ()関数は読み込んだバイト数を返し、 writev ()関数は書き込んだバイト数を返す。 エラーの場合 -1 を返し、errno を適切に設定する。
エラー
read (2) や write (2) と同じエラーが定義されている。 さらに以下のエラーが定義されている:
- EINVAL
- iov_len の合計が ssize_t の範囲をオーバーフローした。もしくは、 ベクタ数 count が 0 より小さいか許可された最大値よりも大きかった。
準拠
4.4BSD ( readv ()と writev ()関数は 4.2BSD で最初に現われた)、POSIX.1-2001。 Linux libc5 では count 引き数の型として size_t を、 これらの関数の返り値として int を使用していた。
Linux での注意
POSIX.1-2001 では、 vector で渡すことができる要素数に上限を設ける実装が認められている。 実装は、 <limits.h> の IOV_MAX を定義することや、実行時に sysconf(_SC_IOV_MAX) の返り値経由で、この上限を広告することができる。 Linux では、この仕組みにより広告される上限は 1024 であり、 この値はカーネルでの上限そのものである。 一方で、glibc のラッパー関数は、その関数の内部で呼ばれるカーネル・ システムコールがこの上限を超過して失敗したことを検出すると、 追加の動作をする。 readv ()の場合、ラッパー関数は vector で指定された全ての要素を格納できる大きさの一時バッファを割り当て、 read ()を呼び出す際にそのバッファを渡し、 そのバッファのデータを vector の各要素の iov_base フィールドが指定する場所にコピーしてから、 そのバッファを解放する。 writev ()のラッパー関数も、同じように一時バッファを使って write ()を呼び出す。
バグ
readv ()や writev ()のようなファイル・ディスクリプタに対する操作を行う関数と、 標準入出力ライブラリの関数をごちゃまぜにして呼ぶのはお薦めしない。 どんな結果になるかは定義されておらず、 おそらく欲しい結果は得られないだろう。