.\" Copyright (C) 2011 Christopher Yeoh .\" and Copyright (C) 2012 Mike Frysinger .\" and Copyright (C) 2012 Michael Kerrisk .\" .\" %%%LICENSE_START(VERBATIM) .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the Linux kernel and libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" %%%LICENSE_END .\" .\" Commit fcf634098c00dd9cd247447368495f0b79be12d1 .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH PROCESS_VM_READV 2 2014\-08\-19 Linux "Linux Programmer's Manual" .SH 名前 process_vm_readv, process_vm_writev \- プロセスのアドレス空間間でデータを転送する .SH 書式 .nf \fB#include \fP \fBssize_t process_vm_readv(pid_t \fP\fIpid\fP\fB,\fP \fB const struct iovec *\fP\fIlocal_iov\fP\fB,\fP \fB unsigned long \fP\fIliovcnt\fP\fB,\fP \fB const struct iovec *\fP\fIremote_iov\fP\fB,\fP \fB unsigned long \fP\fIriovcnt\fP\fB,\fP \fB unsigned long \fP\fIflags\fP\fB);\fP \fBssize_t process_vm_writev(pid_t \fP\fIpid\fP\fB,\fP \fB const struct iovec *\fP\fIlocal_iov\fP\fB,\fP \fB unsigned long \fP\fIliovcnt\fP\fB,\fP \fB const struct iovec *\fP\fIremote_iov\fP\fB,\fP \fB unsigned long \fP\fIriovcnt\fP\fB,\fP \fB unsigned long \fP\fIflags\fP\fB);\fP .fi .sp .in -4n glibc 向けの機能検査マクロの要件 (\fBfeature_test_macros\fP(7) 参照): .in .sp \fBprocess_vm_readv\fP(), \fBprocess_vm_writev\fP(): .PD 0 .ad l .RS 4 \fB_GNU_SOURCE\fP .RE .ad .PD .fi .SH 説明 これらのシステムコールは、 呼び出し元プロセス (「ローカルプロセス」) と \fIpid\fP で指定されるプロセス (「リモートプロセス」) のアドレス空間間でデータを転送する。 データの移動は、 カーネル空間を経由することなく、 2 つのプロセスのアドレス空間間で直接行われる。 \fBprocess_vm_readv\fP() システムコールは、 リモートプロセスからローカルプロセスへデータを転送する。 転送対象のデータは \fIremote_iov\fP と \fIriovcnt\fP で指定される。 \fIremote_iov\fP はプロセス \fIpid\fP におけるアドレス範囲を指定する配列へのポインターで、 \fIriovcnt\fP は \fIremote_iov\fP の要素数を指定する。 データは \fIlocal_iov\fP と \fIliovcnt\fP で指定された場所に転送される。 \fIlocal_iov\fP は呼び出し元プロセスにおけるアドレス範囲を指定する配列で、 \fIliovcnt\fP は \fIlocal_iov\fP の要素数を指定する。 \fBprocess_vm_writev\fP() システムコールは \fBprocess_vm_readv\fP() の逆で、 ローカルプロセスからリモートプロセスにデータを転送する。 転送の方向が違う以外は、 引き数 \fIliovcnt\fP, \fIlocal_iov\fP, \fIriovcnt\fP, \fIremote_iov\fP は \fBprocess_vm_readv\fP() と同じ意味を持つ。 引き数 \fIlocal_iov\fP と \fIremote_iov\fP は \fIiovec\fP 構造体の配列へのポイン タである。 \fIiovec\fP 構造体は \fI\fP で以下のように定義 されている: .in +4n .nf struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes to transfer */ }; .fi .in バッファーは配列の順序で処理される。 つまり、 \fBprocess_vm_readv\fP() は \fIlocal_iov\fP[0] が一杯になるまでデータを詰めてから、 \fIlocal_iov\fP[1] に進むことを意味する。 同様に、 \fIremote_iov\fP[0] を全部読み出してから \fIremote_iov\fP[1] に進み、 以降も同様である。 同様に、 \fBprocess_vm_writev\fP() は \fIlocal_iov[0]\fP の内容を全部読み出してから \fIlocal_iov[1]\fP に進み、 書き込み先でも \fIremote_iov[0]\fP が一杯になってから \fIremote_iov[1]\fP に進む。 長さ \fIremote_iov[i].iov_len\fP と \fIlocal_iov[i].iov_len\fP は同じである必要はない。 したがって、 ローカル側で 1 つのバッファーのデータがリモート側で複数のバッファーに分割されることがあるし、 その逆も起こりえる。 \fIflags\fP 引き数は現在使用されておらず、 0 を設定しなければならない。 .\" In time, glibc might provide a wrapper that works around this limit, .\" as is done for readv()/writev() \fIliovcnt\fP と \fIriovcnt\fP で指定される値は \fBIOV_MAX\fP 以下でなければならない (\fBIOV_MAX\fP は \fI\fP で定義されており、 \fIsysconf(_SC_IOV_MAX)\fP の呼び出しでも入手できる)。 要素数引き数と \fIlocal_iov\fP のチェックは、 すべてのデータ転送に先立って行われる。 要素数が大きすぎる場合や \fIlocal_iov\fP が無効な場合、 アドレスがローカルプロセスがアクセスできない領域を参照している場合は、 配列のどの要素も処理されず、 すぐにエラーが返される。 ただし、 これらのシステムコールは、 実際に読み出し/書き込みを行う直前までリモートプロセスのメモリー領域のチェックを行わない点に注意すること。 結果として、 \fIremote_iov\fP の要素の一つがリモートプロセスで無効なメモリー領域を参照している場合、 部分的な読み出し/書き込み (「返り値」の節を参照) が行われることになる。 これ以降は読み出し/書き込みは行われない。 リモートプロセスから長さ不明のデータ (例えば NULL 終端された C 文字列) を読み出す際で、 リモート側の一つの \fIiovec\fP 要素が複数のメモリーページ (通常は 4KiB) にまたがらないようにしている場合は、 この点に注意が必要である。 (リモートからの読み出しを 2 つの \fIremote_iov\fP 要素に分割し、 1 つの \fIlocal_iov\fP 要素への書き込みにマージすればよい。 最初の読み出しでページ境界まで読み出し、 次の読み出しを次のページ境界から行う。) 他のプロセスからの読み出しや他のプロセスへの書き込みを行うには、 呼び出し元がケーパビリティ \fBCAP_SYS_PTRACE\fP を持っていなければならない、もしくは、 リモートプロセスの実ユーザー ID、 実効ユーザー ID、 保存 set\-user\-ID が呼び出し元の実ユーザー ID と一致し、 かつリモートプロセスの実グループ ID、 実効グループ ID、 保存 set\-group\-ID が呼び出し元の実グループ ID と一致していなければならない。 (ここで必要なアクセス許可は、 リモートプロセスに対して \fBptrace\fP(2) の \fBPTRACE_ATTACH\fP を実行するのに必要な許可と全く同じである。) .SH 返り値 成功すると、 \fBprocess_vm_readv\fP() は読み出したバイト数を返し、 \fBprocess_vm_writev\fP() は書き込んだバイト数を返す。 この返り値は、 読み出し/書き込みが部分的に行われた場合には、 要求された総バイト数よりも小さくなることがある (部分的な転送は \fIiovec\fP 要素単位に行われ、 これらのシステムコールが一つの \fIiovec\fP 要素の一部だけが転送されることはない)。 呼び出し元は返り値を検査して、 部分的な読み出し/書き込みが起こったかどうかを判定できる。 エラーの場合は \-1 が返され、 \fIerrno\fP が適切に設定される。 .SH エラー .TP \fBEINVAL\fP \fIlocal_iov\fP か \fIremote_iov\fP のいずれかの \fIiov_len\fP の合計値が \fIssize_t\fP で表現できる値を超えている。 .TP \fBEINVAL\fP \fIflags\fP が 0 でない。 .TP \fBEINVAL\fP \fIliovcnt\fP か \fIriovcnt\fP が大きすぎる。 .TP \fBEFAULT\fP \fIlocal_iov\fP で指定されたメモリーが呼び出し元がアクセス可能なアドレス空間の外にある。 .TP \fBEFAULT\fP \fIremote_iov\fP で指定されたメモリーがプロセス \fIpid\fP がアクセス可能なアドレス空間の外にある。 .TP \fBENOMEM\fP \fIiovec\fP 構造体の内部コピーのためのメモリーを割り当てできなかった。 .TP \fBEPERM\fP 呼び出し側がプロセス \fIpid\fP のアドレス空間に対するアクセス許可を 持っていない。 .TP \fBESRCH\fP ID が \fIpid\fP のプロセスが存在しない。 .SH バージョン これらのシステムコールは Linux 3.2 で追加された。ライブラリによる サポートは glibc バージョン 2.15 以降で提供されている。 .SH 準拠 これらのシステムコールは非標準で Linux による拡張である。 .SH 注意 \fBprocess_vm_readv\fP() と \fBprocess_vm_writev\fP() により実行されるデータ転送をどのように行ったとしても、 これらがアトミックに行われる保証はない。 .\" Original user is MPI, http://www.mcs.anl.gov/research/projects/mpi/ .\" See also some benchmarks at http://lwn.net/Articles/405284/ .\" and http://marc.info/?l=linux-mm&m=130105930902915&w=2 これらのシステムコールは、 (共有メモリーやパイプなどを使った場合に必要となる 2 回のコピーではなく) 1 回のコピー処理でメッセージの交換を許すことで、 高速なメッセージ送信をできるようにするために設計された。 .SH 例 以下のサンプルコードは \fBprocess_vm_readv\fP() の使用例を示すものである。 このコードは PID 10 のプロセスのアドレス 0x10000 から 20 バイトを読み取り、 最初の 10 バイトを \fIbuf1\fP に、 残りの 10 バイトを \fIbuf2\fP に書き込む。 .sp .nf #include 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; } .fi .SH 関連項目 \fBreadv\fP(2), \fBwritev\fP(2) .SH この文書について この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man\-pages/ に書かれている。