summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDejan Jovicevic <dejan.jovicevic@rt-rk.com>2016-10-11 11:52:47 +0200
committerRiku Voipio <riku.voipio@linaro.org>2016-10-21 15:20:13 +0300
commitf8d00fba27b8667c86b2277af9c2efede28c93c3 (patch)
tree5cdce93b1cf68c26adce094de9bb75cc2de72700
parent0f26386c27d977d523c1e88410414af7739a1730 (diff)
downloadqemu-f8d00fba27b8667c86b2277af9c2efede28c93c3.zip
linux-user: added support for pwritev() system call.
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>
-rw-r--r--linux-user/syscall.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fb6eaa28fc..db697c0bf3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -920,6 +920,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,
@@ -10074,6 +10076,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;