[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] linux-user: add ppoll syscall support
From: |
Mike Frysinger |
Subject: |
[Qemu-devel] [PATCH] linux-user: add ppoll syscall support |
Date: |
Sun, 23 Jan 2011 14:56:03 -0500 |
Some architectures (like Blackfin) only implement ppoll (and skip poll).
So add support for it using existing poll code.
Signed-off-by: Mike Frysinger <address@hidden>
---
linux-user/syscall.c | 29 ++++++++++++++++++++++++++++-
1 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6116ab5..5382662 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6230,18 +6230,42 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
arg1,
ret = do_select(arg1, arg2, arg3, arg4, arg5);
break;
#endif
-#ifdef TARGET_NR_poll
+#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
+# ifdef TARGET_NR_poll
case TARGET_NR_poll:
+# endif
+# ifdef TARGET_NR_ppoll
+ case TARGET_NR_ppoll:
+# endif
{
struct target_pollfd *target_pfd;
unsigned int nfds = arg2;
int timeout = arg3;
struct pollfd *pfd;
unsigned int i;
+ sigset_t origmask;
target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct
target_pollfd) * nfds, 1);
if (!target_pfd)
goto efault;
+
+ if (num == TARGET_NR_ppoll) {
+ sigset_t set;
+ abi_ulong mask;
+
+ if (arg3) {
+ struct timespec timeout_ts;
+ target_to_host_timespec(&timeout_ts, arg3);
+ timeout = timeout_ts.tv_sec * 1000 +
+ timeout_ts.tv_nsec / 1000000;
+ } else
+ timeout = -1;
+
+ mask = arg4;
+ target_to_host_old_sigset(&set, &mask);
+ sigprocmask(SIG_SETMASK, &set, &origmask);
+ }
+
pfd = alloca(sizeof(struct pollfd) * nfds);
for(i = 0; i < nfds; i++) {
pfd[i].fd = tswap32(target_pfd[i].fd);
@@ -6256,6 +6280,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
- sizeof(struct pollfd));
}
unlock_user(target_pfd, arg1, ret);
+
+ if (num == TARGET_NR_ppoll)
+ sigprocmask(SIG_SETMASK, &origmask, NULL);
}
break;
#endif
--
1.7.4.rc2