forked from Minki/linux
ptrace_signal subroutine
This breaks out the ptrace handling from get_signal_to_deliver into a new subroutine. The actual code there doesn't change, and it gets inlined into nearly identical compiled code. This makes the function substantially shorter and thus easier to read, and it nicely isolates the ptrace magic. Signed-off-by: Roland McGrath <roland@redhat.com> Acked-by: Kyle McMartin <kyle@mcmartin.ca> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
0e04388f01
commit
18c98b6527
@ -1757,6 +1757,45 @@ static int do_signal_stop(int signr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ptrace_signal(int signr, siginfo_t *info,
|
||||
struct pt_regs *regs, void *cookie)
|
||||
{
|
||||
if (!(current->ptrace & PT_PTRACED))
|
||||
return signr;
|
||||
|
||||
ptrace_signal_deliver(regs, cookie);
|
||||
|
||||
/* Let the debugger run. */
|
||||
ptrace_stop(signr, 0, info);
|
||||
|
||||
/* We're back. Did the debugger cancel the sig? */
|
||||
signr = current->exit_code;
|
||||
if (signr == 0)
|
||||
return signr;
|
||||
|
||||
current->exit_code = 0;
|
||||
|
||||
/* Update the siginfo structure if the signal has
|
||||
changed. If the debugger wanted something
|
||||
specific in the siginfo structure then it should
|
||||
have updated *info via PTRACE_SETSIGINFO. */
|
||||
if (signr != info->si_signo) {
|
||||
info->si_signo = signr;
|
||||
info->si_errno = 0;
|
||||
info->si_code = SI_USER;
|
||||
info->si_pid = task_pid_vnr(current->parent);
|
||||
info->si_uid = current->parent->uid;
|
||||
}
|
||||
|
||||
/* If the (new) signal is now blocked, requeue it. */
|
||||
if (sigismember(¤t->blocked, signr)) {
|
||||
specific_send_sig_info(signr, info, current);
|
||||
signr = 0;
|
||||
}
|
||||
|
||||
return signr;
|
||||
}
|
||||
|
||||
int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
|
||||
struct pt_regs *regs, void *cookie)
|
||||
{
|
||||
@ -1785,36 +1824,10 @@ relock:
|
||||
if (!signr)
|
||||
break; /* will return 0 */
|
||||
|
||||
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
|
||||
ptrace_signal_deliver(regs, cookie);
|
||||
|
||||
/* Let the debugger run. */
|
||||
ptrace_stop(signr, 0, info);
|
||||
|
||||
/* We're back. Did the debugger cancel the sig? */
|
||||
signr = current->exit_code;
|
||||
if (signr == 0)
|
||||
if (signr != SIGKILL) {
|
||||
signr = ptrace_signal(signr, info, regs, cookie);
|
||||
if (!signr)
|
||||
continue;
|
||||
|
||||
current->exit_code = 0;
|
||||
|
||||
/* Update the siginfo structure if the signal has
|
||||
changed. If the debugger wanted something
|
||||
specific in the siginfo structure then it should
|
||||
have updated *info via PTRACE_SETSIGINFO. */
|
||||
if (signr != info->si_signo) {
|
||||
info->si_signo = signr;
|
||||
info->si_errno = 0;
|
||||
info->si_code = SI_USER;
|
||||
info->si_pid = task_pid_vnr(current->parent);
|
||||
info->si_uid = current->parent->uid;
|
||||
}
|
||||
|
||||
/* If the (new) signal is now blocked, requeue it. */
|
||||
if (sigismember(¤t->blocked, signr)) {
|
||||
specific_send_sig_info(signr, info, current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ka = ¤t->sighand->action[signr-1];
|
||||
|
Loading…
Reference in New Issue
Block a user