The kernel interface, which we are supposed to be implementing, takes a fifth argument: an rusage pointer akin to wait4.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- linux-user/syscall-defs.h | 2 +- linux-user/syscall-proc.inc.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h index a84050a318..f099d98fa3 100644 --- a/linux-user/syscall-defs.h +++ b/linux-user/syscall-defs.h @@ -119,7 +119,7 @@ SYSCALL_DEF(shmget, ARG_DEC, ARG_DEC, ARG_HEX); SYSCALL_DEF_FULL(vfork, .impl = impl_fork); #endif SYSCALL_DEF(wait4, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR); -SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX); +SYSCALL_DEF(waitid, ARG_HEX, ARG_DEC, ARG_PTR, ARG_HEX, ARG_PTR); #ifdef TARGET_NR_waitpid SYSCALL_DEF(waitpid, ARG_DEC, ARG_PTR, ARG_HEX); #endif diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c index 7c647f36d7..b7304b7a42 100644 --- a/linux-user/syscall-proc.inc.c +++ b/linux-user/syscall-proc.inc.c @@ -370,19 +370,30 @@ SYSCALL_IMPL(waitid) id_t id = arg2; abi_ulong target_info = arg3; int options = arg4; + abi_ulong target_rusage = arg5; siginfo_t info, *info_ptr = target_info ? &info : NULL; + struct rusage rusage; + struct rusage *rusage_ptr = target_rusage ? &rusage : NULL; abi_long ret; info.si_pid = 0; - ret = get_errno(safe_waitid(idtype, id, info_ptr, options, NULL)); - if (!is_error(ret) && target_info && info.si_pid != 0) { - target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info, - sizeof(target_siginfo_t), 0); - if (!p) { - return -TARGET_EFAULT; + ret = get_errno(safe_waitid(idtype, id, info_ptr, options, rusage_ptr)); + if (!is_error(ret)) { + if (target_info && info.si_pid != 0) { + target_siginfo_t *p = lock_user(VERIFY_WRITE, target_info, + sizeof(target_siginfo_t), 0); + if (!p) { + return -TARGET_EFAULT; + } + host_to_target_siginfo(p, &info); + unlock_user(p, target_info, sizeof(target_siginfo_t)); + } + if (target_rusage) { + abi_long err = host_to_target_rusage(target_rusage, &rusage); + if (err) { + ret = err; + } } - host_to_target_siginfo(p, &info); - unlock_user(p, target_info, sizeof(target_siginfo_t)); } return ret; } -- 2.17.1