diff mbox series

[v6,20/49] linux-user: Implement rusage argument to waitid

Message ID 20190118213122.22865-20-richard.henderson@linaro.org
State Superseded
Headers show
Series linux-user: Split do_syscall | expand

Commit Message

Richard Henderson Jan. 18, 2019, 9:30 p.m. UTC
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.henderson@linaro.org>

---
 linux-user/syscall-defs.h     |  2 +-
 linux-user/syscall-proc.inc.c | 27 +++++++++++++++++++--------
 2 files changed, 20 insertions(+), 9 deletions(-)

-- 
2.17.2
diff mbox series

Patch

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 37f5bbe197..de4efed9f4 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;
 }