]> Zhao Yanbai Git Server - minix.git/commitdiff
Don't forget about pending signals coming from the kernel.
authorCristiano Giuffrida <cristiano@minix3.org>
Fri, 18 Jun 2010 12:04:20 +0000 (12:04 +0000)
committerCristiano Giuffrida <cristiano@minix3.org>
Fri, 18 Jun 2010 12:04:20 +0000 (12:04 +0000)
servers/pm/misc.c
servers/pm/mproc.h
servers/pm/signal.c

index 13a79e184dbf11d0a6334c1f5d3dce8ee49b5c20..353c15a442325d07fcd57c3d698d43d5140d0db9 100644 (file)
@@ -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);
index 1b5a9b2ea90ec907af0a0d44700616028ca03c9c..b75264bca2c789c56d762079f28bcd197dca3f46 100644 (file)
@@ -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 */
index a13c670e956d2fe7b73f301b1c75935518b22597..48da05fa0a0e41e00699d5e1457144cf088daad8 100644 (file)
@@ -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);