Provided by: manpages-ja-dev_0.5.0.0.20180315+dfsg-1_all 

名前
process_vm_readv, process_vm_writev - プロセスのアドレス空間間でデータを転送する
書式
#include <sys/uio.h> ssize_t process_vm_readv(pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags); ssize_t process_vm_writev(pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags); glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照): process_vm_readv(), process_vm_writev(): _GNU_SOURCE
説明
これらのシステムコールは、 呼び出し元プロセス (「ローカルプロセス」) と pid で指定されるプロセス (「リ モートプロセス」) のアドレス空間間でデータを転送する。 データの移動は、 カーネル空間を経由することなく、 2 つのプロセスのアドレス空間間で直接行われる。 process_vm_readv() システムコールは、 リモートプロセスからローカルプロセスへデータを転送する。 転送対象の データは remote_iov と riovcnt で指定される。 remote_iov はプロセス pid におけるアドレス範囲を指定する配 列へのポインターで、 riovcnt は remote_iov の要素数を指定する。 データは local_iov と liovcnt で指定され た場所に転送される。 local_iov は呼び出し元プロセスにおけるアドレス範囲を指定する配列で、 liovcnt は local_iov の要素数を指定する。 process_vm_writev() システムコールは process_vm_readv() の逆で、 ローカルプロセスからリモートプロセスに データを転送する。 転送の方向が違う以外は、 引き数 liovcnt, local_iov, riovcnt, remote_iov は process_vm_readv() と同じ意味を持つ。 引き数 local_iov と remote_iov は iovec 構造体の配列へのポイン タである。 iovec 構造体は <sys/uio.h> で以 下のように定義 されている: struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes to transfer */ }; バッファーは配列の順序で処理される。 つまり、 process_vm_readv() は local_iov[0] が一杯になるまでデータを 詰めてから、 local_iov[1] に進むことを意味する。 同様に、 remote_iov[0] を全部読み出してから remote_iov[1] に進み、 以降も同様である。 同様に、 process_vm_writev() は local_iov[0] の内容を全部読み出してから local_iov[1] に進み、 書き込み先 でも remote_iov[0] が一杯になってから remote_iov[1] に進む。 長さ remote_iov[i].iov_len と local_iov[i].iov_len は同じである必要はない。 したがって、 ローカル側で 1 つのバッファーのデータがリモート側で複数のバッファーに分割されることがあるし、 その逆も起こりえる。 flags 引き数は現在使用されておらず、 0 を設定しなければならない。 liovcnt と riovcnt で指定される値は IOV_MAX 以下でなければならない (IOV_MAX は <limits.h> で定義されてお り、 sysconf(_SC_IOV_MAX) の呼び出しでも入手できる)。 要素数引き数と local_iov のチェックは、 すべてのデータ転送に先立って行われる。 要素数が大きすぎる場合や local_iov が無効な場合、 アドレスがローカルプロセスがアクセスできない領域を参照している場合は、 配列のど の要素も処理されず、 すぐにエラーが返される。 ただし、 これらのシステムコールは、 実際に読み出し/書き込みを行う直前までリモートプロセスのメモリー領域の チェックを行わない点に注意すること。 結果として、 remote_iov の要素の一つがリモートプロセスで無効なメモ リー領域を参照している場合、 部分的な読み出し/書き込み (「返り値」の節を参照) が行われることになる。 これ 以降は読み出し/書き込みは行われない。 リモートプロセスから長さ不明のデータ (例えば NULL 終端された C 文字 列) を読み出す際で、 リモート側の一つの iovec 要素が複数のメモリーページ (通常は 4KiB) にまたがらないよう にしている場合は、 この点に注意が必要である。 (リモートからの読み出しを 2 つの remote_iov 要素に分割し、 1 つの local_iov 要素への書き込みにマージすればよい。 最初の読み出しでページ境界まで読み出し、 次の読み出 しを次のページ境界から行う。) 他のプロセスからの読み出しや他のプロセスへの書き込みを行うには、 呼び出し元がケーパビリティ CAP_SYS_PTRACE を持っていなければならない、もしくは、 リモートプロセスの実ユーザー ID、 実効ユーザー ID、 保存 set-user-ID が呼び出し元の実ユーザー ID と一致し、 かつリモートプロセスの実グループ ID、 実効グルー プ ID、 保存 set-group-ID が呼び出し元の実グループ ID と一致していなければならない。 (ここで必要なアクセ ス許可は、 リモートプロセスに対して ptrace(2) の PTRACE_ATTACH を実行するのに必要な許可と全く同じであ る。)
返り値
成功すると、 process_vm_readv() は読み出したバイト数を返し、 process_vm_writev() は書き込んだバイト数を返 す。 この返り値は、 読み出し/書き込みが部分的に行われた場合には、 要求された総バイト数よりも小さくなるこ とがある (部分的な転送は iovec 要素単位に行われ、 これらのシステムコールが一つの iovec 要素の一部だけが転 送されることはない)。 呼び出し元は返り値を検査して、 部分的な読み出し/書き込みが起こったかどうかを判定で きる。 エラーの場合は -1 が返され、 errno が適切に設定される。
エラー
EINVAL local_iov か remote_iov のいずれかの iov_len の合計値が ssize_t で表現できる値を超えている。 EINVAL flags が 0 でない。 EINVAL liovcnt か riovcnt が大きすぎる。 EFAULT local_iov で指定されたメモリーが呼び出し元がアクセス可能なアドレス空間の外にある。 EFAULT remote_iov で指定されたメモリーがプロセス pid がアクセス可能なアドレス空間の外にある。 ENOMEM iovec 構造体の内部コピーのためのメモリーを割り当てできなかった。 EPERM 呼び出し側がプロセス pid のアドレス空間に対するアクセス許可を 持っていない。 ESRCH ID が pid のプロセスが存在しない。
バージョン
これらのシステムコールは Linux 3.2 で追加された。ライブラリによる サポートは glibc バージョン 2.15 以降で 提供されている。
準拠
これらのシステムコールは非標準で Linux による拡張である。
注意
process_vm_readv() と process_vm_writev() により実行されるデータ転送をどのように行ったとしても、 これらが アトミックに行われる保証はない。 これらのシステムコールは、 (共有メモリーやパイプなどを使った場合に必要となる 2 回のコピーではなく) 1 回の コピー処理でメッセージの交換を許すことで、 高速なメッセージ送信をできるようにするために設計された。
例
以下のサンプルコードは process_vm_readv() の使用例を示すものである。 このコードは PID 10 のプロセスのアド レス 0x10000 から 20 バイトを読み取り、 最初の 10 バイトを buf1 に、 残りの 10 バイトを buf2 に書き込む。 #include <sys/uio.h> int main(void) { struct iovec local[2]; struct iovec remote[1]; char buf1[10]; char buf2[10]; ssize_t nread; pid_t pid = 10; /* PID of remote process */ local[0].iov_base = buf1; local[0].iov_len = 10; local[1].iov_base = buf2; local[1].iov_len = 10; remote[0].iov_base = (void *) 0x10000; remote[0].iov_len = 20; nread = process_vm_readv(pid, local, 2, remote, 1, 0); if (nread != 20) return 1; else return 0; }
関連項目
readv(2), writev(2)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告 に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。