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

名前

       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_iovriovcnt で指定される。 remote_iov はプロセス pid  におけるアドレス範囲を指定する配
       列へのポインターで、  riovcntremote_iov の要素数を指定する。 データは local_iovliovcnt で指定され
       た場所に転送される。  local_iov  は呼び出し元プロセスにおけるアドレス範囲を指定する配列で、  liovcntlocal_iov の要素数を指定する。

       process_vm_writev()  システムコールは  process_vm_readv() の逆で、 ローカルプロセスからリモートプロセスに
       データを転送する。   転送の方向が違う以外は、   引数   liovcnt,   local_iov,   riovcnt,   remote_iovprocess_vm_readv() と同じ意味を持つ。

       引数 local_iovremote_ioviovec 構造体の配列へのポイン タである。 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_lenlocal_iov[i].iov_len は同じである必要はない。 したがって、 ローカル側で 1
       つのバッファーのデータがリモート側で複数のバッファーに分割されることがあるし、 その逆も起こりえる。

       flags 引数は現在使用されておらず、 0 を設定しなければならない。

       liovcntriovcnt で指定される値は IOV_MAX 以下でなければならない (IOV_MAX<limits.h>  で定義されてお
       り、 sysconf(_SC_IOV_MAX) の呼び出しでも入手できる)。

       要素数引数と  local_iov  のチェックは、  すべてのデータ転送に先立って行われる。  要素数が大きすぎる場合や
       local_iov が無効な場合、 アドレスがローカルプロセスがアクセスできない領域を参照している場合は、  配列のど
       の要素も処理されず、 すぐにエラーが返される。

       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  remote_iov  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 iovec element.  (Instead, split the  remote  read  into
       two  remote_iov  elements  and  have them merge back into a single write local_iov entry.  The first read
       entry goes up to the page boundary, while the second starts on the next page boundary.)

       Permission  to  read  from  or  write  to  another  process  is  governed  by  a   ptrace   access   mode
       PTRACE_MODE_ATTACH_REALCREDS check; see ptrace(2).

返り値

       成功すると、 process_vm_readv() は読み出したバイト数を返し、 process_vm_writev() は書き込んだバイト数を返
       す。 この返り値は、 読み出し/書き込みが部分的に行われた場合には、  要求された総バイト数よりも小さくなるこ
       とがある (部分的な転送は iovec 要素単位に行われ、 これらのシステムコールが一つの iovec 要素の一部だけが転
       送されることはない)。 呼び出し元は返り値を検査して、  部分的な読み出し/書き込みが起こったかどうかを判定で
       きる。

       エラーの場合は -1 が返され、 errno が適切に設定される。

エラー

       EFAULT local_iov で指定されたメモリーが呼び出し元がアクセス可能なアドレス空間の外にある。

       EFAULT remote_iov で指定されたメモリーがプロセス pid がアクセス可能なアドレス空間の外にある。

       EINVAL local_iovremote_iov のいずれかの iov_len の合計値が ssize_t で表現できる値を超えている。

       EINVAL flags が 0 でない。

       EINVAL liovcntriovcnt が大きすぎる。

       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 プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告
       に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。