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>
This commit is contained in:
Timothy E Baldwin 2016-05-27 15:51:55 +01:00 committed by Riku Voipio
parent ef6a778ea2
commit f59ec60610

View File

@ -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