名 前
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_iov と riovcnt で 指 定 さ れ る 。 remote_iov は プ ロ セ ス pid に お け る ア ド レ ス 範 囲 を 指 定 す る 配 列 へ の ポ イ ン タ ー で 、 riovcnt は remote_iov の 要 素 数 を 指 定 す る 。 デ ー タ は local_iov と liovcnt で 指 定 さ れ た 場 所 に 転 送 さ れ る 。 local_iov は 呼 び 出 し 元 プ ロ セ ス に お け る ア ド レ ス 範 囲 を 指 定 す る 配 列 で 、 liovcnt は local_iov の 要 素 数 を 指 定 す る 。
process_vm_writev() シ ス テ ム コ ー ル は process_vm_readv() の 逆 で 、 ロ ー カ ル プ ロ セ ス か ら リ モ ー ト プ ロ セ ス に デ ー タ を 転 送 す る 。 転 送 の 方 向 が 違 う 以 外 は 、 引 き 数 liovcnt, local_iov, riovcnt, remote_iov は process_vm_readv() と 同 じ 意 味 を 持 つ 。 引 き 数 local_iov と remote_iov は iovec 構 造 体 の 配 列 へ の ポ イ ン タ で あ る 。 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_len と
local_iov[i].iov_len は 同 じ
で あ る 必 要 は
な い 。 し た が
っ て 、 ロ ー カ
ル 側 で 1 つ の バ
ッ フ ァ ー の デ
ー タ が リ モ ー
ト 側 で 複 数 の
バ ッ フ ァ ー に
分 割 さ れ る こ
と が あ る し 、
そ の 逆 も 起 こ
り え る 。
flags 引 き 数 は 現 在 使 用 さ れ て お ら ず 、 0 を 設 定 し な け れ ば な ら な い 。
liovcnt と riovcnt で 指 定 さ れ る 値 は 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_iov か remote_iov の い ず れ か の iov_len の 合 計 値 が ssize_t で 表 現 で き る 値 を 超 え て い る 。 | ||||||
EINVAL |
flags が 0 で な い 。 | ||||||
EINVAL |
liovcnt か riovcnt が 大 き す ぎ る 。 | ||||||
EFAULT |
local_iov で 指 定 さ れ た メ モ リ ー が 呼 び 出 し 元 が ア ク セ ス 可 能 な ア ド レ ス 空 間 の 外 に あ る 。 | ||||||
EFAULT |
remote_iov で 指 定 さ れ た メ モ リ ー が プ ロ セ ス pid が ア ク セ ス 可 能 な ア ド レ ス 空 間 の 外 に あ る 。 | ||||||
ENOMEM |
iovec 構 造 体 の 内 部 コ ピ ー の た め の メ モ リ ー を 割 り 当 て で き な か っ た 。
呼 び 出
し 側 が プ ロ セ
ス pid の ア ド レ
ス 空 間 に 対 す
る ア ク セ ス 許
可 を 持 っ て い
な い 。 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 local[0].iov_base
= buf1; nread =
process_vm_readv(pid, local, 2, remote, 1, 0); 関 連 項 目こ の 文 書 に つ い てこ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。 |