.\" 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 2020\-06\-09 Linux "Linux Programmer's Manual" .SH 名前 process_vm_readv, process_vm_writev \- プロセスのアドレス空間間でデータを転送する .SH 書式 .nf \fB#include \fP .PP \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 .PP \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 .PP .RS -4 glibc 向けの機能検査マクロの要件 (\fBfeature_test_macros\fP(7) 参照): .RE .PP \fBprocess_vm_readv\fP(), \fBprocess_vm_writev\fP(): .PD 0 .ad l .RS 4 \fB_GNU_SOURCE\fP .RE .ad .PD .SH 説明 これらのシステムコールは、 呼び出し元プロセス (「ローカルプロセス」) と \fIpid\fP で指定されるプロセス (「リモートプロセス」) のアドレス空間間でデータを転送する。 データの移動は、 カーネル空間を経由することなく、 2 つのプロセスのアドレス空間間で直接行われる。 .PP \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 の要素数を指定する。 .PP \fBprocess_vm_writev\fP() システムコールは \fBprocess_vm_readv\fP() の逆で、 ローカルプロセスからリモートプロセスにデータを転送する。 転送の方向が違う以外は、 引数 \fIliovcnt\fP, \fIlocal_iov\fP, \fIriovcnt\fP, \fIremote_iov\fP は \fBprocess_vm_readv\fP() と同じ意味を持つ。 .PP 引数 \fIlocal_iov\fP と \fIremote_iov\fP は \fIiovec\fP 構造体の配列へのポイン タである。 \fIiovec\fP 構造体は \fI\fP で以下のように定義 されている: .PP .in +4n .EX struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes to transfer */ }; .EE .in .PP バッファーは配列の順序で処理される。 つまり、 \fBprocess_vm_readv\fP() は \fIlocal_iov\fP[0] が一杯になるまでデータを詰めてから、 \fIlocal_iov\fP[1] に進むことを意味する。 同様に、 \fIremote_iov\fP[0] を全部読み出してから \fIremote_iov\fP[1] に進み、 以降も同様である。 .PP 同様に、 \fBprocess_vm_writev\fP() は \fIlocal_iov[0]\fP の内容を全部読み出してから \fIlocal_iov[1]\fP に進み、 書き込み先でも \fIremote_iov[0]\fP が一杯になってから \fIremote_iov[1]\fP に進む。 .PP 長さ \fIremote_iov[i].iov_len\fP と \fIlocal_iov[i].iov_len\fP は同じである必要はない。 したがって、 ローカル側で 1 つのバッファーのデータがリモート側で複数のバッファーに分割されることがあるし、 その逆も起こりえる。 .PP \fIflags\fP 引数は現在使用されておらず、 0 を設定しなければならない。 .PP .\" 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 の呼び出しでも入手できる)。 .PP 要素数引数と \fIlocal_iov\fP のチェックは、 すべてのデータ転送に先立って行われる。 要素数が大きすぎる場合や \fIlocal_iov\fP が無効な場合、 アドレスがローカルプロセスがアクセスできない領域を参照している場合は、 配列のどの要素も処理されず、 すぐにエラーが返される。 .PP Note, however, that these system calls do not check the memory regions in the remote process until just before doing the read/write. Consequently, a partial read/write (see RETURN VALUE) may result if one of the \fIremote_iov\fP elements points to an invalid memory region in the remote process. No further reads/writes will be attempted beyond that point. Keep this in mind when attempting to read data of unknown length (such as C strings that are null\-terminated) from a remote process, by avoiding spanning memory pages (typically 4\ KiB) in a single remote \fIiovec\fP element. (Instead, split the remote read into two \fIremote_iov\fP elements and have them merge back into a single write \fIlocal_iov\fP entry. The first read entry goes up to the page boundary, while the second starts on the next page boundary.) .PP Permission to read from or write to another process is governed by a ptrace access mode \fBPTRACE_MODE_ATTACH_REALCREDS\fP check; see \fBptrace\fP(2). .SH 返り値 成功すると、 \fBprocess_vm_readv\fP() は読み出したバイト数を返し、 \fBprocess_vm_writev\fP() は書き込んだバイト数を返す。 この返り値は、 読み出し/書き込みが部分的に行われた場合には、 要求された総バイト数よりも小さくなることがある (部分的な転送は \fIiovec\fP 要素単位に行われ、 これらのシステムコールが一つの \fIiovec\fP 要素の一部だけが転送されることはない)。 呼び出し元は返り値を検査して、 部分的な読み出し/書き込みが起こったかどうかを判定できる。 .PP エラーの場合は \-1 が返され、 \fIerrno\fP が適切に設定される。 .SH エラー .TP \fBEFAULT\fP \fIlocal_iov\fP で指定されたメモリーが呼び出し元がアクセス可能なアドレス空間の外にある。 .TP \fBEFAULT\fP \fIremote_iov\fP で指定されたメモリーがプロセス \fIpid\fP がアクセス可能なアドレス空間の外にある。 .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 \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() により実行されるデータ転送をどのように行ったとしても、 これらがアトミックに行われる保証はない。 .PP .\" 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 に書き込む。 .PP .EX #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; } .EE .SH 関連項目 \fBreadv\fP(2), \fBwritev\fP(2) .SH この文書について この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は \%https://www.kernel.org/doc/man\-pages/ に書かれている。