mirror of https://github.com/mkerrisk/man-pages
334 lines
8.9 KiB
Groff
334 lines
8.9 KiB
Groff
.\" Copyright (C) 2011 Christopher Yeoh <cyeoh@au1.ibm.com>
|
|
.\" and Copyright (C) 2012 Mike Frysinger <vapier@gentoo.org>
|
|
.\" and Copyright (C) 2012 Michael Kerrisk <mtk.man-pages@gmail.com>
|
|
.\"
|
|
.\" %%%LICENSE_START(VERBATIM)
|
|
.\" 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.
|
|
.\" %%%LICENSE_END
|
|
.\"
|
|
.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1
|
|
.\"
|
|
.TH PROCESS_VM_READV 2 2012-04-25 "Linux" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
process_vm_readv, process_vm_writev \- transfer data between process address spaces
|
|
.SH SYNOPSIS
|
|
.nf
|
|
.B #include <sys/uio.h>
|
|
|
|
.BI "ssize_t process_vm_readv(pid_t " pid ,
|
|
.BI " const struct iovec *" local_iov ,
|
|
.BI " unsigned long " liovcnt ,
|
|
.BI " const struct iovec *" remote_iov ,
|
|
.BI " unsigned long " riovcnt ,
|
|
.BI " unsigned long " flags ");"
|
|
|
|
.BI "ssize_t process_vm_writev(pid_t " pid ,
|
|
.BI " const struct iovec *" local_iov ,
|
|
.BI " unsigned long " liovcnt ,
|
|
.BI " const struct iovec *" remote_iov ,
|
|
.BI " unsigned long " riovcnt ,
|
|
.BI " unsigned long " flags ");"
|
|
.fi
|
|
.SH DESCRIPTION
|
|
These system calls transfer data between the address space
|
|
of the calling process ("the local process") and the process identified by
|
|
.IR pid
|
|
("the remote process").
|
|
The data moves directly between the address spaces of the two processes,
|
|
without passing through kernel space.
|
|
|
|
The
|
|
.BR process_vm_readv ()
|
|
system call transfers data from the remote process to the local process.
|
|
The data to be transferred is identified by
|
|
.IR remote_iov
|
|
and
|
|
.IR riovcnt :
|
|
.IR remote_iov
|
|
is a pointer to an array describing address ranges in the process
|
|
.IR pid ,
|
|
and
|
|
.IR riovcnt
|
|
specifies the number of elements in
|
|
.IR remote_iov .
|
|
The data is transferred to the locations specified by
|
|
.IR local_iov
|
|
and
|
|
.IR liovcnt :
|
|
.IR local_iov
|
|
is a pointer to an array describing address ranges in the calling process,
|
|
and
|
|
.IR liovcnt
|
|
specifies the number of elements in
|
|
.IR local_iov .
|
|
|
|
The
|
|
.BR process_vm_writev ()
|
|
system call is the converse of
|
|
.BR process_vm_readv ()\(emit
|
|
transfers data from the local process to the remote process.
|
|
Other than the direction of the transfer, the arguments
|
|
.IR liovcnt ,
|
|
.IR local_iov ,
|
|
.IR riovcnt ,
|
|
and
|
|
.IR remote_iov
|
|
have the same meaning as for
|
|
.BR process_vm_readv ().
|
|
|
|
The
|
|
.I local_iov
|
|
and
|
|
.I remote_iov
|
|
arguments point to an array of
|
|
.I iovec
|
|
structures, defined in
|
|
.IR <sys/uio.h>
|
|
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 local_iov[0]
|
|
before proceeding to
|
|
.IR local_iov[1] ,
|
|
and so on.
|
|
Likewise,
|
|
.I remote_iov[0]
|
|
is completely read before proceeding to
|
|
.IR remote_iov[1] ,
|
|
and so on.
|
|
|
|
Similarly,
|
|
.BR process_vm_writev ()
|
|
writes out the entire contents of
|
|
.I local_iov[0]
|
|
before proceeding to
|
|
.IR local_iov[1] ,
|
|
and it completely fills
|
|
.I remote_iov[0]
|
|
before proceeding to
|
|
.IR remote_iov[1] .
|
|
|
|
The lengths of
|
|
.I remote_iov[i].iov_len
|
|
and
|
|
.I local_iov[i].iov_len
|
|
do not have to be the same.
|
|
Thus, it is possible to split a single local buffer
|
|
into multiple remote buffers, or vice versa.
|
|
|
|
The
|
|
.I flags
|
|
argument is currently unused and must be set to 0.
|
|
|
|
The values specified in the
|
|
.I liovcnt
|
|
and
|
|
.I riovcnt
|
|
arguments must be less than or equal to
|
|
.BR IOV_MAX
|
|
(defined in
|
|
.I <limits.h>
|
|
or accessible via the call
|
|
.IR sysconf(_SC_IOV_MAX) ).
|
|
.\" In time, glibc might provide a wrapper that works around this limit,
|
|
.\" as is done for readv()/writev()
|
|
|
|
The count arguments and
|
|
.IR local_iov
|
|
are checked before doing any transfers.
|
|
If the counts are too big, or
|
|
.I local_iov
|
|
is invalid,
|
|
or the addresses refer to regions that are inaccessible to the local process,
|
|
none of the vectors will be processed
|
|
and an error will be returned immediately.
|
|
|
|
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
|
|
.I 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 4KiB) in a single remote
|
|
.I iovec
|
|
element.
|
|
(Instead, split the remote read into two
|
|
.I remote_iov
|
|
elements and have them merge back into a single write
|
|
.I local_iov
|
|
entry.
|
|
The first read entry goes up to the page boundary,
|
|
while the second starts on the next page boundary.)
|
|
|
|
In order to read from or write to another process,
|
|
either the caller must have the capability
|
|
.BR CAP_SYS_PTRACE ,
|
|
or
|
|
the real user ID, effective user ID, and saved set-user-ID
|
|
of the remote process must match the real user ID of the caller
|
|
.I and
|
|
the real group ID, effective group ID, and saved set-group-ID
|
|
of the remote process must match the real group ID of the caller.
|
|
(The permission required is exactly the same as that required to perform a
|
|
.BR ptrace (2)
|
|
.BR PTRACE_ATTACH
|
|
on the remote process.)
|
|
.SH RETURN VALUE
|
|
On success,
|
|
.BR process_vm_readv ()
|
|
returns the number of bytes read and
|
|
.BR process_vm_writev ()
|
|
returns the number of bytes written.
|
|
This return value may be less than the total number of requested bytes,
|
|
if a partial read/write occurred.
|
|
(Partial transfers apply at the granularity of
|
|
.I iovec
|
|
elements.
|
|
These system calls won't perform a partial transfer that splits a single
|
|
.I iovec
|
|
element.)
|
|
The caller should check the return value to determine whether
|
|
a partial read/write occurred.
|
|
|
|
On error, \-1 is returned and
|
|
.I errno
|
|
is set appropriately.
|
|
.SH ERRORS
|
|
.TP
|
|
.B EINVAL
|
|
The sum of the
|
|
.I iov_len
|
|
values of either
|
|
.I local_iov
|
|
or
|
|
.I remote_iov
|
|
overflows a
|
|
.I ssize_t
|
|
value.
|
|
.TP
|
|
.B EINVAL
|
|
.I flags
|
|
is not 0.
|
|
.TP
|
|
.B EINVAL
|
|
.I liovcnt
|
|
or
|
|
.I riovcnt
|
|
is too large.
|
|
.TP
|
|
.B EFAULT
|
|
The memory described by
|
|
.I local_iov
|
|
is outside the caller's accessible address space.
|
|
.TP
|
|
.B EFAULT
|
|
The memory described by
|
|
.I remote_iov
|
|
is outside the accessible address space of the process
|
|
.IR pid .
|
|
.TP
|
|
.B ENOMEM
|
|
Could not allocate memory for internal copies of the
|
|
.I iovec
|
|
structures.
|
|
.TP
|
|
.B EPERM
|
|
The caller does not have permission to access the address space of the process
|
|
.IR pid .
|
|
.TP
|
|
.B ESRCH
|
|
No process with ID
|
|
.I pid
|
|
exists.
|
|
.SH VERSIONS
|
|
These system calls were added in Linux 3.2.
|
|
Support is provided in glibc since version 2.15.
|
|
.SH CONFORMING TO
|
|
These system calls are nonstandard Linux extensions.
|
|
.SH NOTES
|
|
The data transfers performed by
|
|
.BR process_vm_readv ()
|
|
and
|
|
.BR process_vm_writev ()
|
|
are not guaranteed to be atomic in any way.
|
|
|
|
These system calls were designed to permit fast message passing
|
|
by allowing messages to be exchanged with a single copy operation
|
|
(rather than the double copy that would be required
|
|
when using, for example, shared memory or pipes).
|
|
.\" Original user is MPI, http://www.mcs.anl.gov/research/projects/mpi/
|
|
.\" See also some benchmarks at http://lwn.net/Articles/405284/
|
|
.\" and http://marc.info/?l=linux-mm&m=130105930902915&w=2
|
|
.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 <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[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)
|