aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/signal.c71
1 files changed, 42 insertions, 29 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 6af1210092c3..cc8303cd093d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1757,6 +1757,45 @@ static int do_signal_stop(int signr)
1757 return 1; 1757 return 1;
1758} 1758}
1759 1759
1760static int ptrace_signal(int signr, siginfo_t *info,
1761 struct pt_regs *regs, void *cookie)
1762{
1763 if (!(current->ptrace & PT_PTRACED))
1764 return signr;
1765
1766 ptrace_signal_deliver(regs, cookie);
1767
1768 /* Let the debugger run. */
1769 ptrace_stop(signr, 0, info);
1770
1771 /* We're back. Did the debugger cancel the sig? */
1772 signr = current->exit_code;
1773 if (signr == 0)
1774 return signr;
1775
1776 current->exit_code = 0;
1777
1778 /* Update the siginfo structure if the signal has
1779 changed. If the debugger wanted something
1780 specific in the siginfo structure then it should
1781 have updated *info via PTRACE_SETSIGINFO. */
1782 if (signr != info->si_signo) {
1783 info->si_signo = signr;
1784 info->si_errno = 0;
1785 info->si_code = SI_USER;
1786 info->si_pid = task_pid_vnr(current->parent);
1787 info->si_uid = current->parent->uid;
1788 }
1789
1790 /* If the (new) signal is now blocked, requeue it. */
1791 if (sigismember(&current->blocked, signr)) {
1792 specific_send_sig_info(signr, info, current);
1793 signr = 0;
1794 }
1795
1796 return signr;
1797}
1798
1760int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, 1799int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
1761 struct pt_regs *regs, void *cookie) 1800 struct pt_regs *regs, void *cookie)
1762{ 1801{
@@ -1785,36 +1824,10 @@ relock:
1785 if (!signr) 1824 if (!signr)
1786 break; /* will return 0 */ 1825 break; /* will return 0 */
1787 1826
1788 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { 1827 if (signr != SIGKILL) {
1789 ptrace_signal_deliver(regs, cookie); 1828 signr = ptrace_signal(signr, info, regs, cookie);
1790 1829 if (!signr)
1791 /* Let the debugger run. */
1792 ptrace_stop(signr, 0, info);
1793
1794 /* We're back. Did the debugger cancel the sig? */
1795 signr = current->exit_code;
1796 if (signr == 0)
1797 continue;
1798
1799 current->exit_code = 0;
1800
1801 /* Update the siginfo structure if the signal has
1802 changed. If the debugger wanted something
1803 specific in the siginfo structure then it should
1804 have updated *info via PTRACE_SETSIGINFO. */
1805 if (signr != info->si_signo) {
1806 info->si_signo = signr;
1807 info->si_errno = 0;
1808 info->si_code = SI_USER;
1809 info->si_pid = task_pid_vnr(current->parent);
1810 info->si_uid = current->parent->uid;
1811 }
1812
1813 /* If the (new) signal is now blocked, requeue it. */
1814 if (sigismember(&current->blocked, signr)) {
1815 specific_send_sig_info(signr, info, current);
1816 continue; 1830 continue;
1817 }
1818 } 1831 }
1819 1832
1820 ka = &current->sighand->action[signr-1]; 1833 ka = &current->sighand->action[signr-1];