From ad5771aa28cc613cf67960e02694fbeca8437940 Mon Sep 17 00:00:00 2001 From: Cristiano Giuffrida Date: Fri, 18 Jun 2010 12:04:20 +0000 Subject: [PATCH] Don't forget about pending signals coming from the kernel. --- servers/pm/misc.c | 1 + servers/pm/mproc.h | 1 + servers/pm/signal.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/servers/pm/misc.c b/servers/pm/misc.c index 13a79e184..353c15a44 100644 --- a/servers/pm/misc.c +++ b/servers/pm/misc.c @@ -79,6 +79,7 @@ PUBLIC int do_procstat() if (m_in.stat_nr == SELF) { mp->mp_reply.sig_set = mp->mp_sigpending; sigemptyset(&mp->mp_sigpending); + sigemptyset(&mp->mp_ksigpending); } else { return(ENOSYS); diff --git a/servers/pm/mproc.h b/servers/pm/mproc.h index 1b5a9b2ea..b75264bca 100644 --- a/servers/pm/mproc.h +++ b/servers/pm/mproc.h @@ -41,6 +41,7 @@ EXTERN struct mproc { sigset_t mp_sigmask; /* signals to be blocked */ sigset_t mp_sigmask2; /* saved copy of mp_sigmask */ sigset_t mp_sigpending; /* pending signals to be handled */ + sigset_t mp_ksigpending; /* bitmap for pending signals from the kernel */ sigset_t mp_sigtrace; /* signals to hand to tracer first */ struct sigaction mp_sigact[_NSIG]; /* as in sigaction(2) */ vir_bytes mp_sigreturn; /* address of C library __sigreturn function */ diff --git a/servers/pm/signal.c b/servers/pm/signal.c index a13c670e9..48da05fa0 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -67,6 +67,7 @@ PUBLIC int do_sigaction() if (svec.sa_handler == SIG_IGN) { sigaddset(&mp->mp_ignore, m_in.sig_nr); sigdelset(&mp->mp_sigpending, m_in.sig_nr); + sigdelset(&mp->mp_ksigpending, m_in.sig_nr); sigdelset(&mp->mp_catch, m_in.sig_nr); } else if (svec.sa_handler == SIG_DFL) { sigdelset(&mp->mp_ignore, m_in.sig_nr); @@ -347,6 +348,7 @@ int ksig; /* non-zero means signal comes from kernel */ if (rmp->mp_flags & VFS_CALL) { sigaddset(&rmp->mp_sigpending, signo); + if(ksig) sigaddset(&rmp->mp_ksigpending, signo); if (!(rmp->mp_flags & PM_SIG_PENDING)) { /* No delay calls: VFS_CALL implies the process called us. */ @@ -406,6 +408,7 @@ int ksig; /* non-zero means signal comes from kernel */ if (!badignore && sigismember(&rmp->mp_sigmask, signo)) { /* Signal should be blocked. */ sigaddset(&rmp->mp_sigpending, signo); + if(ksig) sigaddset(&rmp->mp_ksigpending, signo); return; } @@ -415,6 +418,7 @@ int ksig; /* non-zero means signal comes from kernel */ * will be delivered using the check_pending() calls in do_trace(). */ sigaddset(&rmp->mp_sigpending, signo); + if(ksig) sigaddset(&rmp->mp_ksigpending, signo); return; } if (!badignore && sigismember(&rmp->mp_catch, signo)) { @@ -428,6 +432,7 @@ int ksig; /* non-zero means signal comes from kernel */ if (!(rmp->mp_flags & UNPAUSED)) { /* not yet unpaused; continue later */ sigaddset(&rmp->mp_sigpending, signo); + if(ksig) sigaddset(&rmp->mp_ksigpending, signo); return; } @@ -564,12 +569,15 @@ register struct mproc *rmp; */ int i; + int ksig; for (i = 1; i < _NSIG; i++) { if (sigismember(&rmp->mp_sigpending, i) && !sigismember(&rmp->mp_sigmask, i)) { + ksig = sigismember(&rmp->mp_ksigpending, i); sigdelset(&rmp->mp_sigpending, i); - sig_proc(rmp, i, FALSE /*trace*/, FALSE /* ksig */); + sigdelset(&rmp->mp_ksigpending, i); + sig_proc(rmp, i, FALSE /*trace*/, ksig); if (rmp->mp_flags & VFS_CALL) break; @@ -711,6 +719,7 @@ int signo; /* signal to send to process (1 to _NSIG-1) */ rmp->mp_sigact[signo].sa_handler = SIG_DFL; } sigdelset(&rmp->mp_sigpending, signo); + sigdelset(&rmp->mp_ksigpending, signo); if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK) return(FALSE);