.\" Copyright (C) 2011 Christopher Yeoh .\" Copyright (C) 2012 Mike Frysinger .\" .\" 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. .\" .TH PROCESS_VM_READV 2 2012-03-09 "Linux" "Linux Programmer's Manual" .SH NAME process_vm_readv, process_vm_writev \- read/write from/to another processes' address space .SH SYNOPSIS .B #include .sp .BI "ssize_t process_vm_readv(pid_t " pid , .br .BI " const struct iovec *" lvec , .br .BI " unsigned long " liovcnt , .br .BI " const struct iovec *" rvec , .br .BI " unsigned long " riovcnt , .br .BI " unsigned long " flags ");" .BI "ssize_t process_vm_writev(pid_t " pid , .br .BI " const struct iovec *" lvec , .br .BI " unsigned long " liovcnt , .br .BI " const struct iovec *" rvec , .br .BI " unsigned long " riovcnt , .br .BI " unsigned long " flags ");" .SH DESCRIPTION The .BR process_vm_readv () function reads from the memory locations described by the .I riovcnt buffers from .I rvec in the process identified by .I pid into .I liovcnt buffers described by .I lvec in the current process. The .BR process_vm_writev () function is the inverse of .BR process_vm_readv ()\(emit writes into the memory locations described by .I riovcnt buffers from .I rvec in the process identified by .I pid into .I liovcnt buffers described by .I lvec in the current process. The count values might be individually capped according to .BR UIO_MAXIOV . If the Linux kernel is capped at smaller values, the C library will take care of emulating the limit it exposes (if it is bigger) so the user only needs to care about that (what the C library defines). The pointers .I lvec and .I rvec point to an array of .I iovec structures, defined in .IR as: .in +4n .nf struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes to transfer */ }; .fi .in Buffers are processed in array order. This means that .BR process_vm_readv () completely fills .I lvec[0] before proceeding to .IR lvec[1] , and so on. Along those lines, .I rvec[0] is completely read before proceeding to .I rvec[1] and so on. Similarly, .BR process_vm_writev () writes out the entire contents of .I lvec[0] before proceeding to .IR lvec[1] , and it completely fills .I revc[0] before proceeding to .IR rvec[1] . The lengths of .I rvec[i] and .I lvec[i] do not have to be the same. This allows you to split a single local buffer into multiple remote buffers, or vice versa. The data transfers of .BR process_vm_readv () and .BR process_vm_writev () are not guaranteed to be atomic in any way. The counts and vectors are checked before doing any transfers. So if the counts are too big, or the vectors invalid, or the addresses refer to regions that are inaccessible, none of the previous vectors will be processed and an error will be returned immediately. Keep this in mind when attempting to extract data of unknown length (such as C strings which are NULL terminated) by avoiding spanning memory pages (typically 4KiB). The .I flags parameter is currently unused and must be set to 0. In order to read or write from or to another process you must have the capability .BR CAP_SYS_PTRACE or have the same uid and gid of the target process. The permission required is exactly the same as being able to perform a .BR ptrace (2) ptrace with .BR PTRACE_ATTACH on the target process. .SH "RETURN VALUE" On success, .BR process_vm_readv () returns the number of bytes read while .BR process_vm_writev () returns the number of bytes written. On error, the number of bytes read or written is returned, or -1 is returned if it was unable to read/write any bytes; in either case, .I errno is set appropriately. .SH ERRORS .TP .B EINVAL The sum of the .I iov_len values of either .I lvec or .I rvec overflows a .I ssize_t value. .TP .B EINVAL The value of the .I flags parameter is not 0. .TP .B EFAULT The memory described by .I lvec is outside your accessible address space. .TP .B EFAULT The memory described by .I rvec is outside the accessible address space of process .IR pid . .TP .B ENOMEM Out of memory. .TP .B EPERM .RB ( process_vm_readv ()) You do not have permission to read from process .IR pid . .TP .B EPERM .RB ( process_vm_writev ()) You do not have permission to write to process .IR pid . .TP .B ESRCH .I pid does not exist. .SH VERSIONS These functions are available since glibc 2.15 and Linux 3.2. .SH "CONFORMING TO" These functions are Linux extensions, not in C or POSIX. .SH EXAMPLE The following code sample demonstrates the use of .BR process_vm_readv (). It reads 20 bytes at the address 0x10000 from the process with PID 10 and writes the first 10 bytes into .I buf1 and the second 10 bytes into .IR buf2 . .sp .nf #include int main() { struct iovec local[2]; struct iovec remote[1]; char buf1[10]; char buf2[10]; ssize_t nread; pid_t pid = 10; /* PID of target 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[1].iov_len = 20; nread = process_vm_readv(pid, local, 2, remote, 1, 0); if (nread != 20) return 1; else return 0; } .fi .SH "SEE ALSO" .BR readv (2), .BR writev (2)