Block signals while emulating sigaction. This is a non-interruptible
syscall, and using block_signals() avoids races where the host
signal handler is invoked and tries to examine the signal handler
data structures while we are updating them.
Signed-off-by: Timothy Edward Baldwin <[email protected]>
Message-id:
1441497448[email protected]
[PMM: expanded commit message]
Reviewed-by: Peter Maydell <[email protected]>
Signed-off-by: Peter Maydell <[email protected]>
Signed-off-by: Riku Voipio <[email protected]>
return ret;
}
-/* do_sigaction() return host values and errnos */
+/* do_sigaction() return target values and host errnos */
int do_sigaction(int sig, const struct target_sigaction *act,
struct target_sigaction *oact)
{
int host_sig;
int ret = 0;
- if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP)
- return -EINVAL;
+ if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP) {
+ return -TARGET_EINVAL;
+ }
+
+ if (block_signals()) {
+ return -TARGET_ERESTARTSYS;
+ }
+
k = &sigact_table[sig - 1];
if (oact) {
__put_user(k->_sa_handler, &oact->_sa_handler);