summaryrefslogtreecommitdiff
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:51:55 +0100
committerRiku Voipio <riku.voipio@linaro.org>2016-06-07 16:39:07 +0300
commitf59ec606104ade2443179231fc7a3cb98683ac85 (patch)
treeeca553c490e581c51c9d3134c63fa8c764a25c45 /linux-user/syscall.c
parentef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299 (diff)
downloadqemu-f59ec606104ade2443179231fc7a3cb98683ac85.zip
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> Signed-off-by: Riku Voipio <riku.voipio@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 639b328c74..aa5517c849 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7059,7 +7059,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