aboutsummaryrefslogtreecommitdiff
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorTimothy E Baldwin <T.E.Baldwin99@members.leeds.ac.uk>2016-05-27 15:18:40 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-05-27 15:18:40 +0100
commit5cb0adba4236107e2cd61b8db0c573dd531d158a (patch)
tree4f7242f7e28ead613cafdab0b57f50887fd977bd /linux-user/syscall.c
parentac42af98f74d6502e8ab3f8f7e014f3a1580e323 (diff)
linux-user: pause() should not pause if signal pending
Fix races between signal handling and the pause syscall by reimplementing it using block_signals() and sigsuspend(). (Using safe_syscall(pause) would also work, except that the pause syscall doesn't exist on all architectures.) Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk> Message-id: 1441497448-32489-28-git-send-email-T.E.Baldwin99@members.leeds.ac.uk [PMM: tweaked commit message] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5a346425d6..3fc9c8a187 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6418,7 +6418,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
#ifdef TARGET_NR_pause /* not on alpha */
case TARGET_NR_pause:
- ret = get_errno(pause());
+ if (!block_signals()) {
+ sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
+ }
+ ret = -TARGET_EINTR;
break;
#endif
#ifdef TARGET_NR_utime