diff options
author | Timothy E Baldwin <T.E.Baldwin99@members.leeds.ac.uk> | 2016-05-27 15:18:40 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-05-27 15:18:40 +0100 |
commit | 5cb0adba4236107e2cd61b8db0c573dd531d158a (patch) | |
tree | 4f7242f7e28ead613cafdab0b57f50887fd977bd /linux-user/syscall.c | |
parent | ac42af98f74d6502e8ab3f8f7e014f3a1580e323 (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.c | 5 |
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 |