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/ に書かれている。