|
@@ -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)
|
|
|
- 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);
|
|
|
+ if (signr != SIGKILL) {
|
|
|
+ signr = ptrace_signal(signr, info, regs, cookie);
|
|
|
+ if (!signr)
|
|
|
continue;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
ka = ¤t->sighand->action[signr-1];
|