diff mbox

[PULL,21/22] linux-user: added support for pwritev() system call.

Message ID 1b3f07d272dc7f9a1fdc981796aecd77e990ea8f.1476710353.git.riku.voipio@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Riku Voipio Oct. 17, 2016, 1:24 p.m. UTC
From: Dejan Jovicevic <dejan.jovicevic@rt-rk.com>

This system call performs the same task as the writev() system call,
with the exception of having the fourth argument, offset, which
specifes the file offset at which the input operation is to be performed.
Because of this, the pwritev() implementation is based on the writev()
implementation in linux-user mode.

But, since pwritev() is implemented in the kernel as a 5-argument syscall,
5 arguments are needed to be handled as input and passed to the host
syscall.

The pos_l and pos_h argument of the safe_pwritev() are of type unsigned
long, which can be of different sizes on different platforms. The input
arguments are converted to the appropriate host size when passed to
safe_pwritev().

Signed-off-by: Dejan Jovicevic <dejan.jovicevic@rt-rk.com>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 10c940c..2072b1f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -921,6 +921,8 @@  safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
 safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
 safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt,
               unsigned long, pos_l, unsigned long, pos_h)
+safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt,
+              unsigned long, pos_l, unsigned long, pos_h)
 safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
               socklen_t, addrlen)
 safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
@@ -10092,6 +10094,19 @@  abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
+#if defined(TARGET_NR_pwritev)
+    case TARGET_NR_pwritev:
+        {
+            struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
+            if (vec != NULL) {
+                ret = get_errno(safe_pwritev(arg1, vec, arg3, arg4, arg5));
+                unlock_iovec(vec, arg2, arg3, 0);
+            } else {
+                ret = -host_to_target_errno(errno);
+           }
+        }
+        break;
+#endif
     case TARGET_NR_getsid:
         ret = get_errno(getsid(arg1));
         break;