Manpages

名 前

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 が 無 効 な 場 合 、 ア ド レ ス が ロ ー カ ル プ ロ セ ス が ア ク セ ス で き な い 領 域 を 参 照 し て い る 場 合 は 、 配 列 の ど の 要 素 も 処 理 さ れ ず 、 す ぐ に エ ラ ー が 返 さ れ る 。 た だ し 、 こ れ ら の シ ス テ ム コ ー ル は 、 実 際 に 読 み 出 し /書 き 込 み を 行 う 直 前 ま で リ モ ー ト プ ロ セ ス の メ モ リ ー 領 域 の チ ェ ッ ク を 行 わ な い 点 に 注 意 す る こ と 。 結 果 と し て 、 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_iovremote_iov の い ず れ か の iov_len の 合 計 値 が ssize_t で 表 現 で き る 値 を 超 え て い る 。

EINVAL

flags が 0 で な い 。

EINVAL

liovcntriovcnt が 大 き す ぎ る 。

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