Some architectures (like Blackfin) only implement ppoll (and skip poll). So add support for it using existing poll code.
Signed-off-by: Mike Frysinger <vap...@gentoo.org> --- v2 - call host ppoll() directly linux-user/syscall.c | 28 ++++++++++++++++++++++++++-- 1 files changed, 26 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6116ab5..690ee44 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6230,8 +6230,13 @@ 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; @@ -6242,12 +6247,31 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1); if (!target_pfd) goto efault; + pfd = alloca(sizeof(struct pollfd) * nfds); for(i = 0; i < nfds; i++) { pfd[i].fd = tswap32(target_pfd[i].fd); pfd[i].events = tswap16(target_pfd[i].events); } - ret = get_errno(poll(pfd, nfds, timeout)); + +# ifdef TARGET_NR_ppoll + if (num == TARGET_NR_ppoll) { + struct timespec _timeout_ts, *timeout_ts = &_timeout_ts; + abi_ulong mask = arg4; + sigset_t sigmask; + + if (arg3) + target_to_host_timespec(timeout_ts, arg3); + else + timeout_ts = NULL; + + target_to_host_old_sigset(&sigmask, &mask); + + ret = get_errno(ppoll(pfd, nfds, timeout_ts, &sigmask)); + } else +# endif + ret = get_errno(poll(pfd, nfds, timeout)); + if (!is_error(ret)) { for(i = 0; i < nfds; i++) { target_pfd[i].revents = tswap16(pfd[i].revents); -- 1.7.4.rc2