qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [V2 PATCH 12/12] linux-user: writev Partial Writes


From: Tom Musta
Subject: [Qemu-devel] [V2 PATCH 12/12] linux-user: writev Partial Writes
Date: Tue, 12 Aug 2014 13:53:43 -0500

Although not technically not required by POSIX, the writev system call will
typically write out its buffers individually.  That is, if the first buffer
is written successfully, but the second buffer pointer is invalid, then
the first chuck will be written and its size is returned.

Signed-off-by: Tom Musta <address@hidden>
Reviewed-by: Peter Maydell <address@hidden>
---
V2: Use bool instead of int for "bad_address" per Peter Maydell's review.

 linux-user/syscall.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index edc48e1..fb54f0e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1798,6 +1798,7 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
     abi_ulong total_len, max_len;
     int i;
     int err = 0;
+    bool bad_address = false;
 
     if (count == 0) {
         errno = 0;
@@ -1838,9 +1839,20 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
             vec[i].iov_base = 0;
         } else {
             vec[i].iov_base = lock_user(type, base, len, copy);
+            /* If the first buffer pointer is bad, this is a fault.  But
+             * subsequent bad buffers will result in a partial write; this
+             * is realized by filling the vector with null pointers and
+             * zero lengths. */
             if (!vec[i].iov_base) {
-                err = EFAULT;
-                goto fail;
+                if (i == 0) {
+                    err = EFAULT;
+                    goto fail;
+                } else {
+                    bad_address = true;
+                }
+            }
+            if (bad_address) {
+                len = 0;
             }
             if (len > max_len - total_len) {
                 len = max_len - total_len;
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]