2012-03-04 00:28:15 +01:00
|
|
|
From c2c3a707453bc853b73cf2d3f2663ff2277b6563 Mon Sep 17 00:00:00 2001
|
2011-12-11 03:42:09 +01:00
|
|
|
From: Alexander Graf <agraf@suse.de>
|
|
|
|
Date: Tue, 22 Nov 2011 17:53:40 +0100
|
2012-02-01 00:10:40 +01:00
|
|
|
Subject: [PATCH] linux-user: fix wait* syscall status returns
|
2011-12-11 03:42:09 +01:00
|
|
|
|
|
|
|
When calling wait4 or waitpid with a status pointer and WNOHANG, the
|
|
|
|
syscall can potentially not modify the status pointer input. Now if we
|
|
|
|
have guest code like:
|
|
|
|
|
|
|
|
int status = 0;
|
|
|
|
waitpid(pid, &status, WNOHANG);
|
|
|
|
if (status)
|
|
|
|
<breakage>
|
|
|
|
|
|
|
|
then we have to make sure that in case status did not change we actually
|
|
|
|
return the guest's initialized status variable instead of our own uninitialized.
|
|
|
|
We fail to do so today, as we proxy everything through an uninitialized status
|
|
|
|
variable which for me ended up always containing the last error code.
|
|
|
|
|
|
|
|
This patch fixes some test cases when building yast2-core in OBS for ARM.
|
|
|
|
|
|
|
|
Signed-off-by: Alexander Graf <agraf@suse.de>
|
|
|
|
---
|
|
|
|
linux-user/syscall.c | 8 +++++++-
|
|
|
|
1 files changed, 7 insertions(+), 1 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
|
|
|
|
index 3e6f3bd..f86fe4a 100644
|
|
|
|
--- a/linux-user/syscall.c
|
|
|
|
+++ b/linux-user/syscall.c
|
|
|
|
@@ -4833,7 +4833,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|
|
|
#ifdef TARGET_NR_waitpid
|
|
|
|
case TARGET_NR_waitpid:
|
|
|
|
{
|
|
|
|
- int status;
|
|
|
|
+ int status = 0;
|
|
|
|
+ if (arg2) {
|
|
|
|
+ get_user_s32(status, arg2);
|
|
|
|
+ }
|
|
|
|
ret = get_errno(waitpid(arg1, &status, arg3));
|
|
|
|
if (!is_error(ret) && arg2
|
|
|
|
&& put_user_s32(host_to_target_waitstatus(status), arg2))
|
|
|
|
@@ -6389,6 +6392,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|
|
|
rusage_ptr = &rusage;
|
|
|
|
else
|
|
|
|
rusage_ptr = NULL;
|
|
|
|
+ if (status_ptr) {
|
|
|
|
+ get_user_s32(status, status_ptr);
|
|
|
|
+ }
|
|
|
|
ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
|
|
|
|
if (!is_error(ret)) {
|
|
|
|
if (status_ptr) {
|