From 399644e47874bff147afb19c89228901ac39340e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 21:40:15 +0200 Subject: Adding upstream version 6.05.01. Signed-off-by: Daniel Baumann --- man2/process_vm_readv.2 | 314 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 man2/process_vm_readv.2 (limited to 'man2/process_vm_readv.2') diff --git a/man2/process_vm_readv.2 b/man2/process_vm_readv.2 new file mode 100644 index 0000000..86da35c --- /dev/null +++ b/man2/process_vm_readv.2 @@ -0,0 +1,314 @@ +.\" Copyright (C) 2011 Christopher Yeoh +.\" and Copyright (C) 2012 Mike Frysinger +.\" and Copyright (C) 2012 Michael Kerrisk +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1 +.\" +.TH process_vm_readv 2 2023-05-03 "Linux man-pages 6.05.01" +.SH NAME +process_vm_readv, process_vm_writev \- +transfer data between process address spaces +.SH LIBRARY +Standard C library +.RI ( libc ", " \-lc ) +.SH SYNOPSIS +.nf +.B #include +.PP +.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 +.PP +.RS -4 +Feature Test Macro Requirements for glibc (see +.BR feature_test_macros (7)): +.RE +.PP +.BR process_vm_readv (), +.BR process_vm_writev (): +.nf + _GNU_SOURCE +.fi +.SH DESCRIPTION +These system calls transfer data between the address space +of the calling process ("the local process") and the process identified by +.I pid +("the remote process"). +The data moves directly between the address spaces of the two processes, +without passing through kernel space. +.PP +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 +.I remote_iov +and +.IR riovcnt : +.I remote_iov +is a pointer to an array describing address ranges in the process +.IR pid , +and +.I riovcnt +specifies the number of elements in +.IR remote_iov . +The data is transferred to the locations specified by +.I local_iov +and +.IR liovcnt : +.I local_iov +is a pointer to an array describing address ranges in the calling process, +and +.I liovcnt +specifies the number of elements in +.IR local_iov . +.PP +The +.BR process_vm_writev () +system call is the converse of +.BR process_vm_readv ()\[em]it +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 +.I remote_iov +have the same meaning as for +.BR process_vm_readv (). +.PP +The +.I local_iov +and +.I remote_iov +arguments point to an array of +.I iovec +structures, described in +.BR iovec (3type). +.PP +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. +.PP +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] . +.PP +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. +.PP +The +.I flags +argument is currently unused and must be set to 0. +.PP +The values specified in the +.I liovcnt +and +.I riovcnt +arguments must be less than or equal to +.B IOV_MAX +(defined in +.I +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() +.PP +The count arguments and +.I 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. +.PP +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 4\ KiB) 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.) +.PP +Permission to read from or write to another process +is governed by a ptrace access mode +.B PTRACE_MODE_ATTACH_REALCREDS +check; see +.BR ptrace (2). +.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. +.PP +On error, \-1 is returned and +.I errno +is set to indicate the error. +.SH ERRORS +.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 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 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 STANDARDS +Linux. +.SH HISTORY +Linux 3.2, +glibc 2.15. +.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. +.PP +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 EXAMPLES +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 . +.PP +.\" SRC BEGIN (process_vm_readv.c) +.EX +#define _GNU_SOURCE +#include +#include +#include +\& +int +main(void) +{ + char buf1[10]; + char buf2[10]; + pid_t pid = 10; /* PID of remote process */ + ssize_t nread; + struct iovec local[2]; + struct iovec remote[1]; +\& + 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) + exit(EXIT_FAILURE); +\& + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.BR readv (2), +.BR writev (2) -- cgit v1.2.3