[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall
From: |
Michael Casadevall |
Subject: |
[Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host. |
Date: |
Tue, 16 Feb 2010 05:31:19 -0500 |
Signed-off-by: Michael Casadevall <address@hidden>
---
linux-user/syscall.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 119 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9fb493f..3663451 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -850,6 +850,38 @@ static inline abi_long copy_to_user_timeval(abi_ulong
target_tv_addr,
return 0;
}
+static inline abi_long copy_from_user_timespec(struct timespec *ts,
+ abi_ulong target_ts_addr)
+{
+ struct target_timespec *target_ts;
+
+ if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 1))
+ return -TARGET_EFAULT;
+
+ __get_user(ts->tv_sec, &target_ts->tv_sec);
+ __get_user(ts->tv_nsec, &target_ts->tv_nsec);
+
+ unlock_user_struct(target_ts, target_ts_addr, 0);
+
+ return 0;
+}
+
+
+static inline abi_long copy_to_user_timespec(abi_ulong target_ts_addr,
+ const struct timespec *ts)
+{
+ struct target_timespec *target_ts;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0))
+ return -TARGET_EFAULT;
+
+ __put_user(ts->tv_sec, &target_ts->tv_sec);
+ __put_user(ts->tv_nsec, &target_ts->tv_nsec);
+
+ unlock_user_struct(target_ts, target_ts_addr, 1);
+
+ return 0;
+}
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
#include <mqueue.h>
@@ -949,6 +981,75 @@ static abi_long do_select(int n,
return ret;
}
+#ifdef TARGET_NR_pselect6
+/* do_pselect() must return target values and target errnos. */
+static abi_long do_pselect(int n,
+ abi_ulong rfd_addr, abi_ulong wfd_addr,
+ abi_ulong efd_addr, abi_ulong target_tv_addr,
+ abi_ulong set_addr)
+{
+ fd_set rfds, wfds, efds;
+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+ struct timespec tv, *tv_ptr;
+ sigset_t set, *set_ptr;
+ abi_long ret;
+
+ if (rfd_addr) {
+ if (copy_from_user_fdset(&rfds, rfd_addr, n))
+ return -TARGET_EFAULT;
+ rfds_ptr = &rfds;
+ } else {
+ rfds_ptr = NULL;
+ }
+ if (wfd_addr) {
+ if (copy_from_user_fdset(&wfds, wfd_addr, n))
+ return -TARGET_EFAULT;
+ wfds_ptr = &wfds;
+ } else {
+ wfds_ptr = NULL;
+ }
+ if (efd_addr) {
+ if (copy_from_user_fdset(&efds, efd_addr, n))
+ return -TARGET_EFAULT;
+ efds_ptr = &efds;
+ } else {
+ efds_ptr = NULL;
+ }
+
+ if (target_tv_addr) {
+ if (copy_from_user_timespec(&tv, target_tv_addr))
+ return -TARGET_EFAULT;
+ tv_ptr = &tv;
+ } else {
+ tv_ptr = NULL;
+ }
+
+ /* We don't need to return sigmask to target */
+ if (set_addr) {
+ target_to_host_old_sigset(&set, &set_addr);
+ set_ptr = &set;
+ } else {
+ set_ptr = NULL;
+ }
+
+ ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr, set_ptr));
+
+ if (!is_error(ret)) {
+ if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
+ return -TARGET_EFAULT;
+ if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
+ return -TARGET_EFAULT;
+ if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
+ return -TARGET_EFAULT;
+
+ if (target_tv_addr && copy_to_user_timespec(target_tv_addr, &tv))
+ return -TARGET_EFAULT;
+ }
+
+ return ret;
+}
+#endif
+
static abi_long do_pipe2(int host_pipe[], int flags)
{
#ifdef CONFIG_PIPE2
@@ -5136,6 +5237,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
arg1,
}
break;
#endif
+
+#ifdef TARGET_NR_pselect6
+ case TARGET_NR_pselect6:
+ {
+ abi_ulong inp, outp, exp, tvp, set;
+ long nsel;
+
+ nsel = tswapl(arg1);
+ inp = tswapl(arg2);
+ outp = tswapl(arg3);
+ exp = tswapl(arg4);
+ tvp = tswapl(arg5);
+ set = tswapl(arg6);
+
+ ret = do_pselect(nsel, inp, outp, exp, tvp, set);
+ }
+ break;
+#endif
case TARGET_NR_symlink:
{
void *p2;
--
1.6.6.1
- [Qemu-devel] [PATCH 0/2] support for pselect in linux-user, Michael Casadevall, 2010/02/16
- [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host.,
Michael Casadevall <=