All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] process_vm_{read,write}v(3): initial man pages
@ 2012-03-10  5:42 Mike Frysinger
       [not found] ` <1331358148-17235-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-03-10  5:42 UTC (permalink / raw)
  To: Michael Kerrisk; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

Based heavily on the initial text by Christopher Yeoh.

Signed-off-by: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
---
 man3/process_vm_readv.3  |  205 ++++++++++++++++++++++++++++++++++++++++++++++
 man3/process_vm_writev.3 |    1 +
 2 files changed, 206 insertions(+), 0 deletions(-)
 create mode 100644 man3/process_vm_readv.3
 create mode 100644 man3/process_vm_writev.3

diff --git a/man3/process_vm_readv.3 b/man3/process_vm_readv.3
new file mode 100644
index 0000000..5a2bc0d
--- /dev/null
+++ b/man3/process_vm_readv.3
@@ -0,0 +1,205 @@
+.\" Copyright (C) 2011 Christopher Yeoh <cyeoh-8fk3Idey6ehBDgjK7y7TUQ@public.gmane.org>
+.\" Copyright (C) 2012 Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
+.\"
+.\" 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 3 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 <sys/uio.h>
+.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 \fIriovcnt\fP
+buffers from \fIrvec\fP in the process identified by \fIpid\fP into
+\fIliovcnt\fP buffers described by \fIlvec\fP in the current process. 
+
+The
+.BR process_vm_writev ()
+function is the inverse of
+.BR process_vm_readv ()
+\-\- it writes into the memory locations described by \fIriovcnt\fP buffers
+from \fIrvec\fP in the process identified by \fIpid\fP into \fIliovcnt\fP
+buffers described by \fIlvec\fP in the current process.
+
+The count values might be individually capped according to \fIUIO_MAXIOV\fP.
+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 \fIlvec\fP and \fIrvec\fP point to an array of 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 \fIlvec[0]\fP before proceeding to \fIlvec[1]\fP, and
+so on.  Along those lines, \fIrvec[0]\fP is completely read before
+proceeding to \fIrvec[1]\fP and so on.
+
+Similarly,
+.BR process_vm_writev ()
+writes out the entire contents of \fIlvec[0]\fP before proceeding to
+\fIlvec[1]\fP, and it completely fills \fIrevc[0]\fP before proceeding
+to \fIrvec[1]\fP.
+
+The lengths of \fIrvec[i]\fP and \fIlvec[i]\fP 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 \fIflags\fP 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 \fIiov_len\fP values of either \fIlvec\fP or \fIrvec\fP
+overflows a ssize_t value.
+.TP
+.B EINVAL
+The value of the \fIflags\fP parameter is not 0.
+.TP
+.B EFAULT
+The memory described by \fIlvec\fP is outside your accessible address space.
+.TP
+.B EFAULT
+The memory described by \fIrvec\fP is outside the accessible address space
+of process \fIpid\fP.
+.TP
+.B ENOMEM
+Out of memory.
+.TP
+.B EPERM
+.RB ( process_vm_readv ())
+You do not have permission to read from process \fIpid\fP.
+.TP
+.B EPERM
+.RB ( process_vm_writev ())
+You do not have permission to write to process \fIpid\fP.
+.TP
+.B ESRCH
+\fIpid\fP 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 process_vm_readv().
+It reads 20 bytes at the address 0x10000 from the process with PID 10 
+and writes the first 10 bytes into buf1 and the second 10 bytes into
+buf2.
+.sp
+.nf
+#include <sys/uio.h>
+
+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)
diff --git a/man3/process_vm_writev.3 b/man3/process_vm_writev.3
new file mode 100644
index 0000000..0414fa8
--- /dev/null
+++ b/man3/process_vm_writev.3
@@ -0,0 +1 @@
+.so man3/process_vm_readv.3
-- 
1.7.8.4

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found] ` <1331358148-17235-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-03-19 20:45   ` Michael Kerrisk (man-pages)
       [not found]     ` <CAKgNAkjhzh+zZ+GhOcbKsZpkeAgn6ua5K=zS=0_AUsUQ3GsQ_A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2012-03-20  6:30   ` Michael Kerrisk (man-pages)
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-03-19 20:45 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

Mike,

A quick question about one piece:

> +The count values might be individually capped according to \fIUIO_MAXIOV\fP.
> +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).

I don't see anything in glibc that does this. Have I missed something?

Thanks,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]     ` <CAKgNAkjhzh+zZ+GhOcbKsZpkeAgn6ua5K=zS=0_AUsUQ3GsQ_A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-03-20  0:50       ` Mike Frysinger
       [not found]         ` <201203192050.48882.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-03-20  0:50 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 781 bytes --]

On Monday 19 March 2012 16:45:41 Michael Kerrisk (man-pages) wrote:
> A quick question about one piece:
> > +The count values might be individually capped according to
> > \fIUIO_MAXIOV\fP. +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).
> 
> I don't see anything in glibc that does this. Have I missed something?

i think you're correct.  the code in glibc atm is merely a syscall().  i think 
the idea was to have the C library guarantee that and if moving forward the 
kernel changes, the C library would update by adding a wrapper.  maybe just 
drop this sentence until that day comes ?
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]         ` <201203192050.48882.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-03-20  6:27           ` Michael Kerrisk (man-pages)
       [not found]             ` <CAKgNAkg=3KokH5zFwThOsHt4gaM4fqcauFdmtihCgcFEV8_z1A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-03-20  6:27 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

On Tue, Mar 20, 2012 at 1:50 PM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Monday 19 March 2012 16:45:41 Michael Kerrisk (man-pages) wrote:
>> A quick question about one piece:
>> > +The count values might be individually capped according to
>> > \fIUIO_MAXIOV\fP. +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).
>>
>> I don't see anything in glibc that does this. Have I missed something?
>
> i think you're correct.  the code in glibc atm is merely a syscall().  i think
> the idea was to have the C library guarantee that and if moving forward the
> kernel changes, the C library would update by adding a wrapper.  maybe just
> drop this sentence until that day comes ?

So, does the kernel currently impose a limit on the size of the iovec?
It wasn't immediately clear to me from a quick scan of the source.


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found] ` <1331358148-17235-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  2012-03-19 20:45   ` Michael Kerrisk (man-pages)
@ 2012-03-20  6:30   ` Michael Kerrisk (man-pages)
       [not found]     ` <CAKgNAkj-bss8Tuq3jcPMRpsKCfKgHGSemq5emS48eBXi2JXA_w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2012-03-21 15:43   ` Mike Frysinger
  2012-03-29 19:17   ` Mike Frysinger
  3 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-03-20  6:30 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

And another question about a different part of the page:

> +.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.

Is that last piece really true? On error, how does the syscall return
number of bytes read or written *and* set errno?

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]             ` <CAKgNAkg=3KokH5zFwThOsHt4gaM4fqcauFdmtihCgcFEV8_z1A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-03-21  3:25               ` Christopher Yeoh
  2012-03-21  4:05                 ` Mike Frysinger
  2012-03-21  3:57               ` Mike Frysinger
  1 sibling, 1 reply; 28+ messages in thread
From: Christopher Yeoh @ 2012-03-21  3:25 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Mike Frysinger, linux-man-u79uwXL29TY76Z2rM5mHXA

On Tue, 20 Mar 2012 19:27:31 +1300
"Michael Kerrisk (man-pages)" <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> On Tue, Mar 20, 2012 at 1:50 PM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
> wrote:
> > On Monday 19 March 2012 16:45:41 Michael Kerrisk (man-pages) wrote:
> >> A quick question about one piece:
> >> > +The count values might be individually capped according to
> >> > \fIUIO_MAXIOV\fP. +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).
> >>
> >> I don't see anything in glibc that does this. Have I missed
> >> something?
> >
> > i think you're correct.  the code in glibc atm is merely a
> > syscall().  i think the idea was to have the C library guarantee
> > that and if moving forward the kernel changes, the C library would
> > update by adding a wrapper.  maybe just drop this sentence until
> > that day comes ?
> 
> So, does the kernel currently impose a limit on the size of the iovec?
> It wasn't immediately clear to me from a quick scan of the source.
> 
> 

The code calls rw_copy_check_uvector which does check that the iovecs
are smaller than UIO_MAXIOV.

Note that the following bit is not strictly true:
  "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."

Whilst the code does check that memory regions in the process calling
the system calls are accessible before any work is done, it does not
check the memory regions in the remote process until just before doing
the read/write. So in that case you can end up with a partial
read/write if one of the iovec elements for the remote process points
to an invalid memory region. No further read/writes will be attempted
after this point though.

Regards,

Chris
-- 
cyeoh-hXjcm30GF6XQT0dZR+AlfA@public.gmane.org

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]             ` <CAKgNAkg=3KokH5zFwThOsHt4gaM4fqcauFdmtihCgcFEV8_z1A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2012-03-21  3:25               ` Christopher Yeoh
@ 2012-03-21  3:57               ` Mike Frysinger
  1 sibling, 0 replies; 28+ messages in thread
From: Mike Frysinger @ 2012-03-21  3:57 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 1414 bytes --]

On Tuesday 20 March 2012 02:27:31 Michael Kerrisk (man-pages) wrote:
> On Tue, Mar 20, 2012 at 1:50 PM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> > On Monday 19 March 2012 16:45:41 Michael Kerrisk (man-pages) wrote:
> >> A quick question about one piece:
> >> > +The count values might be individually capped according to
> >> > \fIUIO_MAXIOV\fP. +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).
> >> 
> >> I don't see anything in glibc that does this. Have I missed something?
> > 
> > i think you're correct.  the code in glibc atm is merely a syscall().  i
> > think the idea was to have the C library guarantee that and if moving
> > forward the kernel changes, the C library would update by adding a
> > wrapper.  maybe just drop this sentence until that day comes ?
> 
> So, does the kernel currently impose a limit on the size of the iovec?
> It wasn't immediately clear to me from a quick scan of the source.

yes.  process_vm_{read,write}v() in mm/process_vm_access.c calls 
process_vm_rw() which calls rw_copy_check_uvector() in fs/read_write.c and one 
of the first things it does:
    if (nr_segs > UIO_MAXIOV) {
        ret = -EINVAL;
        goto out;
    }
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
  2012-03-21  3:25               ` Christopher Yeoh
@ 2012-03-21  4:05                 ` Mike Frysinger
  0 siblings, 0 replies; 28+ messages in thread
From: Mike Frysinger @ 2012-03-21  4:05 UTC (permalink / raw)
  To: Christopher Yeoh
  Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 873 bytes --]

On Tuesday 20 March 2012 23:25:10 Christopher Yeoh wrote:
> Note that the following bit is not strictly true:
>   "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."
> 
> Whilst the code does check that memory regions in the process calling
> the system calls are accessible before any work is done, it does not
> check the memory regions in the remote process until just before doing
> the read/write. So in that case you can end up with a partial
> read/write if one of the iovec elements for the remote process points
> to an invalid memory region. No further read/writes will be attempted
> after this point though.

yes, i missed the "check_access" logic in rw_copy_check_uvector()
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]     ` <CAKgNAkj-bss8Tuq3jcPMRpsKCfKgHGSemq5emS48eBXi2JXA_w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-03-21  4:09       ` Mike Frysinger
  2012-03-21  4:13       ` Christopher Yeoh
  1 sibling, 0 replies; 28+ messages in thread
From: Mike Frysinger @ 2012-03-21  4:09 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 726 bytes --]

On Tuesday 20 March 2012 02:30:29 Michael Kerrisk (man-pages) wrote:
> And another question about a different part of the page:
> > +.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.
> 
> Is that last piece really true? On error, how does the syscall return
> number of bytes read or written *and* set errno?

yeah, this was a mistranslation by me from the .txt to the man page
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]     ` <CAKgNAkj-bss8Tuq3jcPMRpsKCfKgHGSemq5emS48eBXi2JXA_w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2012-03-21  4:09       ` Mike Frysinger
@ 2012-03-21  4:13       ` Christopher Yeoh
  1 sibling, 0 replies; 28+ messages in thread
From: Christopher Yeoh @ 2012-03-21  4:13 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, Mike Frysinger,
	linux-man-u79uwXL29TY76Z2rM5mHXA

On Tue, 20 Mar 2012 19:30:29 +1300
"Michael Kerrisk (man-pages)" <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> And another question about a different part of the page:
> 
> > +.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.
> 
> Is that last piece really true? On error, how does the syscall return
> number of bytes read or written *and* set errno?

Sorry the original was badly written on my part.

On error, one of two things will happen:
  - number of bytes read or written returned if a partial read/write
    occurred OR
  - -1 returned and errno set appropriately

Regards,

Chris

-- 
cyeoh-hXjcm30GF6XQT0dZR+AlfA@public.gmane.org

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found] ` <1331358148-17235-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  2012-03-19 20:45   ` Michael Kerrisk (man-pages)
  2012-03-20  6:30   ` Michael Kerrisk (man-pages)
@ 2012-03-21 15:43   ` Mike Frysinger
       [not found]     ` <201203211143.37042.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  2012-03-29 19:17   ` Mike Frysinger
  3 siblings, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-03-21 15:43 UTC (permalink / raw)
  To: Michael Kerrisk; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 122 bytes --]

Michael: should i fold in the updates that came from this thread and send a 
v2, or are you going to tackle it ?
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]     ` <201203211143.37042.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-03-21 18:29       ` Michael Kerrisk (man-pages)
       [not found]         ` <CAKgNAkiNiG42ZtjYszYWBQWsvsk+c-mHhucER6Umt3esUvRCKg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-03-21 18:29 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

On Thu, Mar 22, 2012 at 4:43 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> Michael: should i fold in the updates that came from this thread and send a
> v2, or are you going to tackle it ?

I'll work on a draft, and have it out for review in a few days.

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]         ` <CAKgNAkiNiG42ZtjYszYWBQWsvsk+c-mHhucER6Umt3esUvRCKg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-03-29 18:42           ` Michael Kerrisk (man-pages)
       [not found]             ` <CAKgNAkiEF6yTN-S-7-7L3Bu+QQyBepgocQM5S=CAOZ+npBQmEQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-03-29 18:42 UTC (permalink / raw)
  To: Mike Frysinger, Christopher Yeoh; +Cc: linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 9297 bytes --]

On Thu, Mar 22, 2012 at 7:29 AM, Michael Kerrisk (man-pages)
<mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Thu, Mar 22, 2012 at 4:43 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
>> Michael: should i fold in the updates that came from this thread and send a
>> v2, or are you going to tackle it ?
>
> I'll work on a draft, and have it out for review in a few days.

Mike, Chris,

Here's a heavily edited version of the page that Mike sent in. Since I
might have messed something up, could I ask you two to take a good
look at this page?

Thanks,

Michael

.\" Copyright (C) 2011 Christopher Yeoh <cyeoh-8fk3Idey6ehBDgjK7y7TUQ@public.gmane.org>
.\" and Copyright (C) 2012 Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
.\" and Copyright (C) 2012 Michael Kerrisk <mtk.man-pages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
.\"
.\" 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.
.\"
.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1
.\"	
.TH PROCESS_VM_READV 2 2012-03-25 "Linux" "Linux Programmer's Manual"
.SH NAME
process_vm_readv, process_vm_writev \- transfer data between process
address spaces
.SH SYNOPSIS
.B #include <sys/uio.h>
.nf
.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 process
.I pid
to the calling process.
The data to be transferred is identified by
.IR remote_vec
and
.IR riovcnt :
.IR remote_vec
is a pointer to an array describing address ranges in the process
.IR pid ,
and
.IR riovcnt
specifies the number of items in
.IR remote_vec .
The data is transferred to the locations specified by
.IR local_vec
and
.IR liovcnt :
.IR local_vec
is a pointer to an array describing address ranges in the calling process,
and
.IR liovcnt
specifies the specifies the number of items in
.IR local_vec .

The
.BR process_vm_writev ()
system call is the converse of
.BR process_vm_readv ()\(emit
transfers data from the calling process to the process
.IR pid .
Other than the direction of the transfer, the arguments
.IR liovcnt ,
.IR local_vec ,
.IR liovcnt ,
and
.IR remote_vec
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_vec[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_vec
are checked before doing any transfers.
If the counts are too big, or
.I local_vec
is invalid,
or the addresses refer to regions that are inaccessible in the local process,
none of the vectors will be processed and an
error will be returned immediately.
.\" FIXME: What does the following sentence mean?
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).

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 may result if one of the
.I remote_vec
elements points to an invalid memory region in the remote process.
No further reads/writes will be attempted beyond that point.

In order to read from or write to another process,
either the caller must have the capability
.BR CAP_SYS_PTRACE ,
or
the real, effective, and saved set user IDs
of the target process must match the real user ID of the caller
.I and
the real, effective, and saved set group IDs
of the target 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 target 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.
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
Out of memory.
.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 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)

[-- Attachment #2: process_vm_readv.2 --]
[-- Type: application/octet-stream, Size: 8621 bytes --]

.\" 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>
.\"
.\" 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.
.\"
.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1
.\"	
.TH PROCESS_VM_READV 2 2012-03-25 "Linux" "Linux Programmer's Manual"
.SH NAME
process_vm_readv, process_vm_writev \- transfer data between process address spaces
.SH SYNOPSIS
.B #include <sys/uio.h>
.nf
.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 process
.I pid
to the calling process.
The data to be transferred is identified by
.IR remote_vec
and
.IR riovcnt :
.IR remote_vec
is a pointer to an array describing address ranges in the process
.IR pid ,
and
.IR riovcnt
specifies the number of items in
.IR remote_vec .
The data is transferred to the locations specified by
.IR local_vec
and
.IR liovcnt :
.IR local_vec
is a pointer to an array describing address ranges in the calling process,
and
.IR liovcnt
specifies the specifies the number of items in
.IR local_vec .

The
.BR process_vm_writev ()
system call is the converse of
.BR process_vm_readv ()\(emit
transfers data from the calling process to the process
.IR pid .
Other than the direction of the transfer, the arguments
.IR liovcnt ,
.IR local_vec ,
.IR liovcnt ,
and
.IR remote_vec
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_vec[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_vec
are checked before doing any transfers.
If the counts are too big, or
.I local_vec
is invalid,
or the addresses refer to regions that are inaccessible in the local process,
none of the vectors will be processed and an
error will be returned immediately.
.\" FIXME: What does the following sentence mean?
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).

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 may result if one of the
.I remote_vec
elements points to an invalid memory region in the remote process.
No further reads/writes will be attempted beyond that point.

In order to read from or write to another process,
either the caller must have the capability
.BR CAP_SYS_PTRACE ,
or
the real, effective, and saved set user IDs
of the target process must match the real user ID of the caller
.I and
the real, effective, and saved set group IDs
of the target 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 target 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.
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
Out of memory.
.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 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)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found] ` <1331358148-17235-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
                     ` (2 preceding siblings ...)
  2012-03-21 15:43   ` Mike Frysinger
@ 2012-03-29 19:17   ` Mike Frysinger
       [not found]     ` <201203291517.46815.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  3 siblings, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-03-29 19:17 UTC (permalink / raw)
  To: Michael Kerrisk; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 4496 bytes --]

On Thursday 29 March 2012 14:42:49 Michael Kerrisk (man-pages) wrote:
> .SH SYNOPSIS
> .B #include <sys/uio.h>
> .nf
> .BI "ssize_t process_vm_readv(pid_t " pid ,

i think there should be a blank line between sys/uio.h and the prototypes

> 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").

you set up terms as if you're going to use them, but then later continue to 
say "the calling process" and "the process identified by pid".  wouldn't it be 
better to convert all of those to "local" and "remote" ?

> .IR remote_vec
> is a pointer to an array describing address ranges in the process
> .IR pid ,
> and
> .IR riovcnt
> specifies the number of items in

personally, i prefer "elements" over "items"

> is a pointer to an array describing address ranges in the calling process,
> and
> .IR liovcnt
> specifies the specifies the number of items in

got "specifies the" duplicated here

> The
> .BR process_vm_writev ()
> system call is the converse of

"inverse" might be better, but either works

> .BR process_vm_readv ()\(emit
> transfers data from the calling process to the process

i don't like how this renders.  there's no spacing between the func and the 
next word:
	process_vm_readv()—it

imo, there should be:
	process_vm_readv() — it

> or the addresses refer to regions that are inaccessible in the local
> process,

might be better phrased as:
	... inaccessible to the local process ...

> .\" FIXME: What does the following sentence mean?

heh, i was just about to suggest a clarification.  consider the case where you 
want to read a C string from a remote process.  you don't know its length, so 
it is probably cheaper to read too much data and then discard the rest than it 
is to read it byte by byte in a single syscall.

further consider the string lies in the last page of a valid mapping.  you 
don't want to always say "read 500 bytes" because if the first 200 bytes are 
the last 200 bytes of the last page, the remaining 300 bytes cover invalid 
memory, and so no data will be read.

instead, you'd split the remote read array into two elements and have them 
merge back into a single write array entry.  the first read entry goes up to 
the page boundary while the second starts on the next page boundary.

> 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).

... by avoiding spanning memory pages (typically 4KiB) in a single iovec 
element.

> 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 may result if one of the
> .I remote_vec
> elements points to an invalid memory region in the remote process.
> No further reads/writes will be attempted beyond that point.

should clarify that the partial read/write applies to iovec elements 
granularity and not byte granularity.  i.e. the syscall won't return a partial 
read that splits a single iovect element.

> In order to read from or write to another process,
> either the caller must have the capability
> .BR CAP_SYS_PTRACE ,
> or
> the real, effective, and saved set user IDs
> of the target process must match the real user ID of the caller
> .I and
> the real, effective, and saved set group IDs
> of the target process must match the real group ID of the caller.

the "set" phrasing here seems off.  should it be:
	... the real, effective, and saved set of user IDs ...
i.e. add the word "of"

> .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.
> The caller should check the return value to determine whether
> a partial read/write occurred.)

the stuff in parenthesis is larger than not.  maybe just drop them ?

> .B ENOMEM
> Out of memory.

this can be a little confusing to people based on the statements earlier that 
the kernel doesn't do any copying.  perhaps clarify that the kernel allocates 
copies of the iovec structures/etc... for internal state and that can OOM ?
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]             ` <CAKgNAkiEF6yTN-S-7-7L3Bu+QQyBepgocQM5S=CAOZ+npBQmEQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-02  2:03               ` Christopher Yeoh
  2012-04-14  1:08                 ` Michael Kerrisk (man-pages)
  0 siblings, 1 reply; 28+ messages in thread
From: Christopher Yeoh @ 2012-04-02  2:03 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w, Mike Frysinger,
	linux-man-u79uwXL29TY76Z2rM5mHXA

On Fri, 30 Mar 2012 07:42:49 +1300
"Michael Kerrisk (man-pages)" <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> On Thu, Mar 22, 2012 at 7:29 AM, Michael Kerrisk (man-pages)
> <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > On Thu, Mar 22, 2012 at 4:43 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
> > wrote:
> >> Michael: should i fold in the updates that came from this thread
> >> and send a v2, or are you going to tackle it ?
> >
> > I'll work on a draft, and have it out for review in a few days.
> 
> Mike, Chris,
> 
> Here's a heavily edited version of the page that Mike sent in. Since I
> might have messed something up, could I ask you two to take a good
> look at this page?
> 

....

> 
> The
> .BR process_vm_readv ()
> system call transfers data from the process
> .I pid
> to the calling process.
> The data to be transferred is identified by
> .IR remote_vec

Just a typo, but I think you mean remote_iov here instead of remote_vec
(it occurs in a few places below as well). There's some cases of
local_vec instead of local_iov too.

Regards,

Chris
-- 
cyeoh-hXjcm30GF6XQT0dZR+AlfA@public.gmane.org

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]     ` <201203291517.46815.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-04-14  1:07       ` Michael Kerrisk (man-pages)
       [not found]         ` <CAKgNAkiKL64_H2QT6v0hsP-=cM3w=wGJbjaph+JMq6R+Knhysg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-14  1:07 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

Hi Mike,

On Fri, Mar 30, 2012 at 8:17 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Thursday 29 March 2012 14:42:49 Michael Kerrisk (man-pages) wrote:
>> .SH SYNOPSIS
>> .B #include <sys/uio.h>
>> .nf
>> .BI "ssize_t process_vm_readv(pid_t " pid ,
>
> i think there should be a blank line between sys/uio.h and the prototypes

Yes.

>> 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").
>
> you set up terms as if you're going to use them, but then later continue to
> say "the calling process" and "the process identified by pid".  wouldn't it be
> better to convert all of those to "local" and "remote" ?

Thanks. I'll convert at least some of them.

>> .IR remote_vec
>> is a pointer to an array describing address ranges in the process
>> .IR pid ,
>> and
>> .IR riovcnt
>> specifies the number of items in
>
> personally, i prefer "elements" over "items"

Yes, "elements" is better.

>> is a pointer to an array describing address ranges in the calling process,
>> and
>> .IR liovcnt
>> specifies the specifies the number of items in
>
> got "specifies the" duplicated here

Thanks.

>> The
>> .BR process_vm_writev ()
>> system call is the converse of
>
> "inverse" might be better, but either works

I prefer converse.

>> .BR process_vm_readv ()\(emit
>> transfers data from the calling process to the process
>
> i don't like how this renders.  there's no spacing between the func and the
> next word:
>        process_vm_readv()—it
>
> imo, there should be:
>        process_vm_readv() — it

Normal typographic usage of em-dash is without surrounding spaces.

>> or the addresses refer to regions that are inaccessible in the local
>> process,
>
> might be better phrased as:
>        ... inaccessible to the local process ...

Yes.

>> .\" FIXME: What does the following sentence mean?
>
> heh, i was just about to suggest a clarification.  consider the case where you
> want to read a C string from a remote process.  you don't know its length, so
> it is probably cheaper to read too much data and then discard the rest than it
> is to read it byte by byte in a single syscall.
>
> further consider the string lies in the last page of a valid mapping.  you
> don't want to always say "read 500 bytes" because if the first 200 bytes are
> the last 200 bytes of the last page, the remaining 300 bytes cover invalid
> memory, and so no data will be read.
>
> instead, you'd split the remote read array into two elements and have them
> merge back into a single write array entry.  the first read entry goes up to
> the page boundary while the second starts on the next page boundary.
>
>> 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).
>
> ... by avoiding spanning memory pages (typically 4KiB) in a single iovec
> element.

Thanks for the clear explanation, and the crisp addition to the
man-page text. I also adapted a piece of your explanation to add into
the page after the above sentence:

==
(Instead, split the remote read array into two
.I iovec
elements and have them merge back into a single write array entry.
The first read entry goes up to the page boundary,
while the second starts on the next page boundary.)
==

However, as I look at the text, there is still a nagging doubt. The
paragraph starts
==
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.
==

That seems to contradict the advice "Instead, split the remote read
array", because surely if the second of the iovec elements refers to
an inaccessible region, then as stated in the early part of the
paragraph, "none of the vectors will be processed". And the advice
refers to the "remote read array".

What am I missing? I suspect the advice should instead apply to the
*remote_iov*, and perhaps be placed in the following paragraph.

>> 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 may result if one of the
>> .I remote_vec
>> elements points to an invalid memory region in the remote process.
>> No further reads/writes will be attempted beyond that point.
>
> should clarify that the partial read/write applies to iovec elements
> granularity and not byte granularity.  i.e. the syscall won't return a partial
> read that splits a single iovect element.

I added this text under RETURN VALUE:

==
(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.)
==

And again a question does "a single iovec element" here apply to the
remove iovec elements, the local iovec elements, or both?

>> In order to read from or write to another process,
>> either the caller must have the capability
>> .BR CAP_SYS_PTRACE ,
>> or
>> the real, effective, and saved set user IDs
>> of the target process must match the real user ID of the caller
>> .I and
>> the real, effective, and saved set group IDs
>> of the target process must match the real group ID of the caller.
>
> the "set" phrasing here seems off.  should it be:
>        ... the real, effective, and saved set of user IDs ...
> i.e. add the word "of"

What is meant here is "real user ID, effective user ID, or saved
set-user-ID", but I was trying to be economical with characters. I'll
instead write the full text then. since it appears my economy is a
little unclear.

>> .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.
>> The caller should check the return value to determine whether
>> a partial read/write occurred.)
>
> the stuff in parenthesis is larger than not.  maybe just drop them ?

Yes.

>> .B ENOMEM
>> Out of memory.
>
> this can be a little confusing to people based on the statements earlier that
> the kernel doesn't do any copying.  perhaps clarify that the kernel allocates
> copies of the iovec structures/etc... for internal state and that can OOM ?

I'll make it:

==
Could not allocate memory for internal copies of the
.I iovec
structures.
==

Thanks for these comments Mike.

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
  2012-04-02  2:03               ` Christopher Yeoh
@ 2012-04-14  1:08                 ` Michael Kerrisk (man-pages)
  0 siblings, 0 replies; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-14  1:08 UTC (permalink / raw)
  To: Christopher Yeoh; +Cc: Mike Frysinger, linux-man-u79uwXL29TY76Z2rM5mHXA

Hello Chris,

On Mon, Apr 2, 2012 at 2:03 PM, Christopher Yeoh <cyeoh-8fk3Idey6ehBDgjK7y7TUQ@public.gmane.org> wrote:
> On Fri, 30 Mar 2012 07:42:49 +1300
> "Michael Kerrisk (man-pages)" <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> On Thu, Mar 22, 2012 at 7:29 AM, Michael Kerrisk (man-pages)
>> <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> > On Thu, Mar 22, 2012 at 4:43 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
>> > wrote:
>> >> Michael: should i fold in the updates that came from this thread
>> >> and send a v2, or are you going to tackle it ?
>> >
>> > I'll work on a draft, and have it out for review in a few days.
>>
>> Mike, Chris,
>>
>> Here's a heavily edited version of the page that Mike sent in. Since I
>> might have messed something up, could I ask you two to take a good
>> look at this page?
>>
>
> ....
>
>>
>> The
>> .BR process_vm_readv ()
>> system call transfers data from the process
>> .I pid
>> to the calling process.
>> The data to be transferred is identified by
>> .IR remote_vec
>
> Just a typo, but I think you mean remote_iov here instead of remote_vec
> (it occurs in a few places below as well). There's some cases of
> local_vec instead of local_iov too.

Yes. Thanks for catching that.

Cheers,

Michael


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]         ` <CAKgNAkiKL64_H2QT6v0hsP-=cM3w=wGJbjaph+JMq6R+Knhysg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-14  1:10           ` Michael Kerrisk (man-pages)
  2012-04-14  4:36           ` Mike Frysinger
  1 sibling, 0 replies; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-14  1:10 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

And, for completeness, here's the current draft.

Cheers,

Michael

.\" Copyright (C) 2011 Christopher Yeoh <cyeoh-8fk3Idey6ehBDgjK7y7TUQ@public.gmane.org>
.\" and Copyright (C) 2012 Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
.\" and Copyright (C) 2012 Michael Kerrisk <mtk.man-pages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
.\"
.\" 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.
.\"
.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1
.\"	
.TH PROCESS_VM_READV 2 2012-04-14 "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 liovcnt ,
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.
Keep this in mind when attempting to
extract data of unknown length (such as C strings that are null-terminated)
by avoiding spanning memory pages (typically 4KiB) in a single
.I iovec
element.
(Instead, split the remote read array into two
.I iovec
elements and have them merge back into a single write array entry.
The first read entry goes up to the page boundary,
while the second starts on the next page boundary.)

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 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.

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)
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]         ` <CAKgNAkiKL64_H2QT6v0hsP-=cM3w=wGJbjaph+JMq6R+Knhysg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2012-04-14  1:10           ` Michael Kerrisk (man-pages)
@ 2012-04-14  4:36           ` Mike Frysinger
       [not found]             ` <201204140036.28834.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  1 sibling, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-04-14  4:36 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 4460 bytes --]

On Friday 13 April 2012 21:07:28 Michael Kerrisk wrote:
> On Fri, Mar 30, 2012 at 8:17 AM, Mike Frysinger wrote:
> > On Thursday 29 March 2012 14:42:49 Michael Kerrisk wrote:
> >> .\" FIXME: What does the following sentence mean?
> > 
> > heh, i was just about to suggest a clarification.  consider the case
> > where you want to read a C string from a remote process.  you don't know
> > its length, so it is probably cheaper to read too much data and then
> > discard the rest than it is to read it byte by byte in a single syscall.
> > 
> > further consider the string lies in the last page of a valid mapping.
> >  you don't want to always say "read 500 bytes" because if the first 200
> > bytes are the last 200 bytes of the last page, the remaining 300 bytes
> > cover invalid memory, and so no data will be read.
> > 
> > instead, you'd split the remote read array into two elements and have
> > them merge back into a single write array entry.  the first read entry
> > goes up to the page boundary while the second starts on the next page
> > boundary.
> > 
> >> 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).
> > 
> > ... by avoiding spanning memory pages (typically 4KiB) in a single iovec
> > element.
> 
> Thanks for the clear explanation, and the crisp addition to the
> man-page text. I also adapted a piece of your explanation to add into
> the page after the above sentence:
> 
> ==
> (Instead, split the remote read array into two
> .I iovec
> elements and have them merge back into a single write array entry.
> The first read entry goes up to the page boundary,
> while the second starts on the next page boundary.)
> ==
> 
> However, as I look at the text, there is still a nagging doubt. The
> paragraph starts
> ==
> 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.
> ==
> 
> That seems to contradict the advice "Instead, split the remote read
> array", because surely if the second of the iovec elements refers to
> an inaccessible region, then as stated in the early part of the
> paragraph, "none of the vectors will be processed". And the advice
> refers to the "remote read array".
> 
> What am I missing? I suspect the advice should instead apply to the
> *remote_iov*, and perhaps be placed in the following paragraph.

the new text you added describes the remote args (the stuff that needs 
splitting).  the existing text you refer to describes the local args.  i don't 
see any contradiction here -- the kernel first checks the local memory regions 
to make sure the local process has full access to its own regions before 
processing anything, and then it processes the remote memory regions one 
element at a time while doing the actual transfers.

> >> 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 may result if one of the
> >> .I remote_vec
> >> elements points to an invalid memory region in the remote process.
> >> No further reads/writes will be attempted beyond that point.
> > 
> > should clarify that the partial read/write applies to iovec elements
> > granularity and not byte granularity.  i.e. the syscall won't return a
> > partial read that splits a single iovect element.
> 
> I added this text under RETURN VALUE:
> 
> ==
> (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.)
> ==
> 
> And again a question does "a single iovec element" here apply to the
> remove iovec elements, the local iovec elements, or both?

if any local iovec element is invalid, then it returns immediately without any 
transferring of data.  this is because the local process should know what 
is/isn't valid about itself before making any requests.  however, it's hard 
for it to know about the remote process, so the remote elements are "looser" 
in checking (which is a good thing).
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]             ` <201204140036.28834.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-04-14 21:22               ` Michael Kerrisk (man-pages)
       [not found]                 ` <CAKgNAkjh46Bpar7qkJBn_r4D1qtFkbK_QLVfE3ESgEuaYMGp5g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-14 21:22 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

Mike,

On Sat, Apr 14, 2012 at 4:36 PM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Friday 13 April 2012 21:07:28 Michael Kerrisk wrote:
>> On Fri, Mar 30, 2012 at 8:17 AM, Mike Frysinger wrote:
>> > On Thursday 29 March 2012 14:42:49 Michael Kerrisk wrote:
>> >> .\" FIXME: What does the following sentence mean?
>> >
>> > heh, i was just about to suggest a clarification.  consider the case
>> > where you want to read a C string from a remote process.  you don't know
>> > its length, so it is probably cheaper to read too much data and then
>> > discard the rest than it is to read it byte by byte in a single syscall.
>> >
>> > further consider the string lies in the last page of a valid mapping.
>> >  you don't want to always say "read 500 bytes" because if the first 200
>> > bytes are the last 200 bytes of the last page, the remaining 300 bytes
>> > cover invalid memory, and so no data will be read.
>> >
>> > instead, you'd split the remote read array into two elements and have
>> > them merge back into a single write array entry.  the first read entry
>> > goes up to the page boundary while the second starts on the next page
>> > boundary.
>> >
>> >> 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).
>> >
>> > ... by avoiding spanning memory pages (typically 4KiB) in a single iovec
>> > element.
>>
>> Thanks for the clear explanation, and the crisp addition to the
>> man-page text. I also adapted a piece of your explanation to add into
>> the page after the above sentence:
>>
>> ==
>> (Instead, split the remote read array into two
>> .I iovec
>> elements and have them merge back into a single write array entry.
>> The first read entry goes up to the page boundary,
>> while the second starts on the next page boundary.)
>> ==
>>
>> However, as I look at the text, there is still a nagging doubt. The
>> paragraph starts
>> ==
>> 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.
>> ==
>>
>> That seems to contradict the advice "Instead, split the remote read
>> array", because surely if the second of the iovec elements refers to
>> an inaccessible region, then as stated in the early part of the
>> paragraph, "none of the vectors will be processed". And the advice
>> refers to the "remote read array".
>>
>> What am I missing? I suspect the advice should instead apply to the
>> *remote_iov*, and perhaps be placed in the following paragraph.
>
> the new text you added describes the remote args (the stuff that needs
> splitting).  the existing text you refer to describes the local args.  i don't
> see any contradiction here -- the kernel first checks the local memory regions
> to make sure the local process has full access to its own regions before
> processing anything, and then it processes the remote memory regions one
> element at a time while doing the actual transfers.

I think you've missed my point. The text starts out with a sentence
describing the checks performed on the count arguments and local_iov.
Then it says "Keep this in mind" (i.e., the aforementioned point) and
gives some advice about how to avoid a certain kind of error when
specifying remote_iov. All of the technical details are correct, but
the logic of the explanation is (it seems to me) broken. The "Keep
this in mind" suggests that the second part of the text is dependent
on the explanation given in the first part, when in fact it is not. If
you still don't see what I mean, can you describe to me what "this" in
"Keep this in mind" refers to.

It seems to me that the "Keep this in mind" part belons with the
*following* paragraph, like so:

==
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 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
.I iovec
element.
(Instead, split the remote read into two
.I remote_iov
elements and have them merge back into a single write array entry.
The first read entry goes up to the page boundary,
while the second starts on the next page boundary.)
==

Does that not make better sense?

>> >> 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 may result if one of the
>> >> .I remote_vec
>> >> elements points to an invalid memory region in the remote process.
>> >> No further reads/writes will be attempted beyond that point.
>> >
>> > should clarify that the partial read/write applies to iovec elements
>> > granularity and not byte granularity.  i.e. the syscall won't return a
>> > partial read that splits a single iovect element.
>>
>> I added this text under RETURN VALUE:
>>
>> ==
>> (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.)
>> ==
>>
>> And again a question does "a single iovec element" here apply to the
>> remove iovec elements, the local iovec elements, or both?
>
> if any local iovec element is invalid, then it returns immediately without any
> transferring of data.  this is because the local process should know what
> is/isn't valid about itself before making any requests.  however, it's hard
> for it to know about the remote process, so the remote elements are "looser"
> in checking (which is a good thing).

Perhaps I'm too clogged up with a cold, but I couldn't draw an answer
to the question " does "a single iovec element" here apply to the
remote iovec elements, the local iovec elements, or both?" from your
reply.

Mike, thanks for persisting so far with trying to clarify things.

Cheers,

Michael



-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                 ` <CAKgNAkjh46Bpar7qkJBn_r4D1qtFkbK_QLVfE3ESgEuaYMGp5g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-22 18:56                   ` Michael Kerrisk (man-pages)
  2012-04-24  4:24                   ` Mike Frysinger
  1 sibling, 0 replies; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-22 18:56 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: linux-man, Christopher Yeoh

Hi Mike,

Ping!

Cheers,

Michael


---------- Forwarded message ----------
From: Michael Kerrisk (man-pages) <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Sun, Apr 15, 2012 at 9:22 AM
Subject: Re: [PATCH] process_vm_{read,write}v(3): initial man pages
To: Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
Cc: Christopher Yeoh <cyeoh-8fk3Idey6ehBDgjK7y7TUQ@public.gmane.org>, linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org


Mike,

On Sat, Apr 14, 2012 at 4:36 PM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Friday 13 April 2012 21:07:28 Michael Kerrisk wrote:
>> On Fri, Mar 30, 2012 at 8:17 AM, Mike Frysinger wrote:
>> > On Thursday 29 March 2012 14:42:49 Michael Kerrisk wrote:
>> >> .\" FIXME: What does the following sentence mean?
>> >
>> > heh, i was just about to suggest a clarification.  consider the case
>> > where you want to read a C string from a remote process.  you don't know
>> > its length, so it is probably cheaper to read too much data and then
>> > discard the rest than it is to read it byte by byte in a single syscall.
>> >
>> > further consider the string lies in the last page of a valid mapping.
>> >  you don't want to always say "read 500 bytes" because if the first 200
>> > bytes are the last 200 bytes of the last page, the remaining 300 bytes
>> > cover invalid memory, and so no data will be read.
>> >
>> > instead, you'd split the remote read array into two elements and have
>> > them merge back into a single write array entry.  the first read entry
>> > goes up to the page boundary while the second starts on the next page
>> > boundary.
>> >
>> >> 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).
>> >
>> > ... by avoiding spanning memory pages (typically 4KiB) in a single iovec
>> > element.
>>
>> Thanks for the clear explanation, and the crisp addition to the
>> man-page text. I also adapted a piece of your explanation to add into
>> the page after the above sentence:
>>
>> ==
>> (Instead, split the remote read array into two
>> .I iovec
>> elements and have them merge back into a single write array entry.
>> The first read entry goes up to the page boundary,
>> while the second starts on the next page boundary.)
>> ==
>>
>> However, as I look at the text, there is still a nagging doubt. The
>> paragraph starts
>> ==
>> 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.
>> ==
>>
>> That seems to contradict the advice "Instead, split the remote read
>> array", because surely if the second of the iovec elements refers to
>> an inaccessible region, then as stated in the early part of the
>> paragraph, "none of the vectors will be processed". And the advice
>> refers to the "remote read array".
>>
>> What am I missing? I suspect the advice should instead apply to the
>> *remote_iov*, and perhaps be placed in the following paragraph.
>
> the new text you added describes the remote args (the stuff that needs
> splitting).  the existing text you refer to describes the local args.  i don't
> see any contradiction here -- the kernel first checks the local memory regions
> to make sure the local process has full access to its own regions before
> processing anything, and then it processes the remote memory regions one
> element at a time while doing the actual transfers.

I think you've missed my point. The text starts out with a sentence
describing the checks performed on the count arguments and local_iov.
Then it says "Keep this in mind" (i.e., the aforementioned point) and
gives some advice about how to avoid a certain kind of error when
specifying remote_iov. All of the technical details are correct, but
the logic of the explanation is (it seems to me) broken. The "Keep
this in mind" suggests that the second part of the text is dependent
on the explanation given in the first part, when in fact it is not. If
you still don't see what I mean, can you describe to me what "this" in
"Keep this in mind" refers to.

It seems to me that the "Keep this in mind" part belons with the
*following* paragraph, like so:

==
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 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
.I iovec
element.
(Instead, split the remote read into two
.I remote_iov
elements and have them merge back into a single write array entry.
The first read entry goes up to the page boundary,
while the second starts on the next page boundary.)
==

Does that not make better sense?

>> >> 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 may result if one of the
>> >> .I remote_vec
>> >> elements points to an invalid memory region in the remote process.
>> >> No further reads/writes will be attempted beyond that point.
>> >
>> > should clarify that the partial read/write applies to iovec elements
>> > granularity and not byte granularity.  i.e. the syscall won't return a
>> > partial read that splits a single iovect element.
>>
>> I added this text under RETURN VALUE:
>>
>> ==
>> (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.)
>> ==
>>
>> And again a question does "a single iovec element" here apply to the
>> remove iovec elements, the local iovec elements, or both?
>
> if any local iovec element is invalid, then it returns immediately without any
> transferring of data.  this is because the local process should know what
> is/isn't valid about itself before making any requests.  however, it's hard
> for it to know about the remote process, so the remote elements are "looser"
> in checking (which is a good thing).

Perhaps I'm too clogged up with a cold, but I couldn't draw an answer
to the question " does "a single iovec element" here apply to the
remote iovec elements, the local iovec elements, or both?" from your
reply.

Mike, thanks for persisting so far with trying to clarify things.

Cheers,

Michael



--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/


-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                 ` <CAKgNAkjh46Bpar7qkJBn_r4D1qtFkbK_QLVfE3ESgEuaYMGp5g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2012-04-22 18:56                   ` Michael Kerrisk (man-pages)
@ 2012-04-24  4:24                   ` Mike Frysinger
       [not found]                     ` <201204240024.56967.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  1 sibling, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-04-24  4:24 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 1801 bytes --]

On Saturday 14 April 2012 17:22:06 Michael Kerrisk (man-pages) wrote:
> 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.

to be clear, the arrays themselves are checked to see if they point to valid 
memory, as are the count values, before the transfer takes place.  so if 
local_iov/remote_iov are NULL or similarly invalid, nothing happens.  in 
practice, this generally equates to the same thing, but there is a slight edge 
case -- if the remote_iov array is mostly valid, but the remote count value 
causes it to spill into invalid memory, nothing will be processed.  note that 
i'm talking about the storage of the elements themselves and not the memory 
they point to.  but maybe being super pedantic here isn't necessary ...

> 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 may result if one of the

any mention of a partial read/write should point to the text clarifying what 
that means (perhaps something as simple as "see RETURN VALUE for more info".

> Does that not make better sense?

it does

> Perhaps I'm too clogged up with a cold, but I couldn't draw an answer
> to the question " does "a single iovec element" here apply to the
> remote iovec elements, the local iovec elements, or both?" from your
> reply.

wrt partial transfers, remote only afaict.  this is by virtue of nothing being 
transferred at all if any of the local elements are invalid.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                     ` <201204240024.56967.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-04-24  9:07                       ` Michael Kerrisk (man-pages)
       [not found]                         ` <CAKgNAki+hiCAdGe9ExFsY2MwsLE=yvHib+nb5WQbXqtBXCqHMw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-24  9:07 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

Hi Mike,

On Tue, Apr 24, 2012 at 4:24 PM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Saturday 14 April 2012 17:22:06 Michael Kerrisk (man-pages) wrote:
>> 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.
>
> to be clear, the arrays themselves are checked to see if they point to valid
> memory, as are the count values, before the transfer takes place.  so if
> local_iov/remote_iov are NULL or similarly invalid, nothing happens.  in
> practice, this generally equates to the same thing, but there is a slight edge
> case -- if the remote_iov array is mostly valid, but the remote count value
> causes it to spill into invalid memory, nothing will be processed.  note that
> i'm talking about the storage of the elements themselves and not the memory
> they point to.  but maybe being super pedantic here isn't necessary ...
>
>> 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 may result if one of the
>
> any mention of a partial read/write should point to the text clarifying what
> that means (perhaps something as simple as "see RETURN VALUE for more info".

I added a reference to RETURN VALUE there.

>> Does that not make better sense?
>
> it does

Good.

>> Perhaps I'm too clogged up with a cold, but I couldn't draw an answer
>> to the question " does "a single iovec element" here apply to the
>> remote iovec elements, the local iovec elements, or both?" from your
>> reply.
>
> wrt partial transfers, remote only afaict.  this is by virtue of nothing being
> transferred at all if any of the local elements are invalid.

Okay -- I added the word "remote".

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                         ` <CAKgNAki+hiCAdGe9ExFsY2MwsLE=yvHib+nb5WQbXqtBXCqHMw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-24  9:11                           ` Michael Kerrisk (man-pages)
       [not found]                             ` <CAKgNAkg2ag9cR217km4vLM0kZYANfayNt=4mvfiObnL4LY3ztQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-24  9:11 UTC (permalink / raw)
  To: Mike Frysinger, Christopher Yeoh; +Cc: linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 9422 bytes --]

Christopher,

Mike's provided me with a lot of input on the page, and there's been a
number of changes to it. Before I publish, would you be able to do a
final check of the text. I've appended and attached the page.

Cheers,

Michael


.\" Copyright (C) 2011 Christopher Yeoh <cyeoh-8fk3Idey6ehBDgjK7y7TUQ@public.gmane.org>
.\" and Copyright (C) 2012 Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
.\" and Copyright (C) 2012 Michael Kerrisk <mtk.man-pages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
.\"
.\" 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.
.\"
.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1
.\"	
.TH PROCESS_VM_READV 2 2012-04-14 "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 liovcnt ,
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 remove_iov
elements and have them merge back into a single write array 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)

[-- Attachment #2: process_vm_readv.2 --]
[-- Type: application/octet-stream, Size: 9111 bytes --]

.\" 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>
.\"
.\" 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.
.\"
.\" Commit fcf634098c00dd9cd247447368495f0b79be12d1
.\"	
.TH PROCESS_VM_READV 2 2012-04-14 "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 liovcnt ,
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
.I iovec
element.
(Instead, split the remote read into two 
.I remove_iov
elements and have them merge back into a single write array 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)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                             ` <CAKgNAkg2ag9cR217km4vLM0kZYANfayNt=4mvfiObnL4LY3ztQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-24 17:49                               ` Mike Frysinger
       [not found]                                 ` <201204241349.31377.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-04-24 17:49 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 1985 bytes --]

On Tuesday 24 April 2012 05:11:54 Michael Kerrisk (man-pages) wrote:
> 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 ,

maybe add the word "remote" here:
	... in the remote process pid, ...

> 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,

calling -> local

> The
> .BR process_vm_writev ()
> system call is the converse of
> .BR process_vm_readv ()\(emit

this renders as:
	... process_vm_readv()—it transfers ...

were you going to kill off that weird dash, or just add spacing around it ?

> Other than the direction of the transfer, the arguments
> .IR liovcnt ,
> .IR local_iov ,
> .IR liovcnt ,
> and
> .IR remote_iov
> have the same meaning as for
> .BR process_vm_readv ().

that second liovcnt is supposed to be riovcnt

> 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)

should that RETURN VALUE be bolded ?

> 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 remove_iov
> elements and have them merge back into a single write array entry.

maybe change "array" to "local_iov"
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                                 ` <201204241349.31377.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2012-04-25  2:16                                   ` Michael Kerrisk (man-pages)
       [not found]                                     ` <CAKgNAkj2hUUZCpG7F-1VpnAeNuM0aHtSqvoK26UbSj3bxnrsog-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Michael Kerrisk (man-pages) @ 2012-04-25  2:16 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

On Wed, Apr 25, 2012 at 5:49 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Tuesday 24 April 2012 05:11:54 Michael Kerrisk (man-pages) wrote:
>> 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 ,
>
> maybe add the word "remote" here:
>        ... in the remote process pid, ...
>
>> 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,
>
> calling -> local

The last two wordings were actually deliberate emphasize the
connections pid == remove, caller == local, so I'll leave as is.

>> The
>> .BR process_vm_writev ()
>> system call is the converse of
>> .BR process_vm_readv ()\(emit
>
> this renders as:
>        ... process_vm_readv()—it transfers ...
>
> were you going to kill off that weird dash, or just add spacing around it ?

As noted earlier, normal English typesetting convention is no spaces
around an em-dash...

>> Other than the direction of the transfer, the arguments
>> .IR liovcnt ,
>> .IR local_iov ,
>> .IR liovcnt ,
>> and
>> .IR remote_iov
>> have the same meaning as for
>> .BR process_vm_readv ().
>
> that second liovcnt is supposed to be riovcnt

Thanks!

>> 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)
>
> should that RETURN VALUE be bolded ?

No. (man-pages convention.)

>> 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 remove_iov
>> elements and have them merge back into a single write array entry.
>
> maybe change "array" to "local_iov"

Yes, better.

Thanks for checking this over again, Mike.

Christoper?

Cheers,

Michael

-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                                     ` <CAKgNAkj2hUUZCpG7F-1VpnAeNuM0aHtSqvoK26UbSj3bxnrsog-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-11-19 19:01                                       ` Mike Frysinger
       [not found]                                         ` <201211191401.10726.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 28+ messages in thread
From: Mike Frysinger @ 2012-11-19 19:01 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 31 bytes --]

can we merge these now ?
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] process_vm_{read,write}v(3): initial man pages
       [not found]                                         ` <201211191401.10726.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2013-03-03  4:05                                           ` Mike Frysinger
  0 siblings, 0 replies; 28+ messages in thread
From: Mike Frysinger @ 2013-03-03  4:05 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Christopher Yeoh, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: Text/Plain, Size: 109 bytes --]

On Monday 19 November 2012 14:01:09 Mike Frysinger wrote:
> can we merge these now ?

another ping ...
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2013-03-03  4:05 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-10  5:42 [PATCH] process_vm_{read,write}v(3): initial man pages Mike Frysinger
     [not found] ` <1331358148-17235-1-git-send-email-vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-03-19 20:45   ` Michael Kerrisk (man-pages)
     [not found]     ` <CAKgNAkjhzh+zZ+GhOcbKsZpkeAgn6ua5K=zS=0_AUsUQ3GsQ_A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-03-20  0:50       ` Mike Frysinger
     [not found]         ` <201203192050.48882.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-03-20  6:27           ` Michael Kerrisk (man-pages)
     [not found]             ` <CAKgNAkg=3KokH5zFwThOsHt4gaM4fqcauFdmtihCgcFEV8_z1A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-03-21  3:25               ` Christopher Yeoh
2012-03-21  4:05                 ` Mike Frysinger
2012-03-21  3:57               ` Mike Frysinger
2012-03-20  6:30   ` Michael Kerrisk (man-pages)
     [not found]     ` <CAKgNAkj-bss8Tuq3jcPMRpsKCfKgHGSemq5emS48eBXi2JXA_w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-03-21  4:09       ` Mike Frysinger
2012-03-21  4:13       ` Christopher Yeoh
2012-03-21 15:43   ` Mike Frysinger
     [not found]     ` <201203211143.37042.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-03-21 18:29       ` Michael Kerrisk (man-pages)
     [not found]         ` <CAKgNAkiNiG42ZtjYszYWBQWsvsk+c-mHhucER6Umt3esUvRCKg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-03-29 18:42           ` Michael Kerrisk (man-pages)
     [not found]             ` <CAKgNAkiEF6yTN-S-7-7L3Bu+QQyBepgocQM5S=CAOZ+npBQmEQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-02  2:03               ` Christopher Yeoh
2012-04-14  1:08                 ` Michael Kerrisk (man-pages)
2012-03-29 19:17   ` Mike Frysinger
     [not found]     ` <201203291517.46815.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-04-14  1:07       ` Michael Kerrisk (man-pages)
     [not found]         ` <CAKgNAkiKL64_H2QT6v0hsP-=cM3w=wGJbjaph+JMq6R+Knhysg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-14  1:10           ` Michael Kerrisk (man-pages)
2012-04-14  4:36           ` Mike Frysinger
     [not found]             ` <201204140036.28834.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-04-14 21:22               ` Michael Kerrisk (man-pages)
     [not found]                 ` <CAKgNAkjh46Bpar7qkJBn_r4D1qtFkbK_QLVfE3ESgEuaYMGp5g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-22 18:56                   ` Michael Kerrisk (man-pages)
2012-04-24  4:24                   ` Mike Frysinger
     [not found]                     ` <201204240024.56967.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-04-24  9:07                       ` Michael Kerrisk (man-pages)
     [not found]                         ` <CAKgNAki+hiCAdGe9ExFsY2MwsLE=yvHib+nb5WQbXqtBXCqHMw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-24  9:11                           ` Michael Kerrisk (man-pages)
     [not found]                             ` <CAKgNAkg2ag9cR217km4vLM0kZYANfayNt=4mvfiObnL4LY3ztQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-24 17:49                               ` Mike Frysinger
     [not found]                                 ` <201204241349.31377.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2012-04-25  2:16                                   ` Michael Kerrisk (man-pages)
     [not found]                                     ` <CAKgNAkj2hUUZCpG7F-1VpnAeNuM0aHtSqvoK26UbSj3bxnrsog-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-19 19:01                                       ` Mike Frysinger
     [not found]                                         ` <201211191401.10726.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2013-03-03  4:05                                           ` Mike Frysinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.