Thu Jun 6 16:12:39 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
authorRoland McGrath <roland@gnu.org>
Thu, 6 Jun 1996 20:49:22 +0000 (20:49 +0000)
committerRoland McGrath <roland@gnu.org>
Thu, 6 Jun 1996 20:49:22 +0000 (20:49 +0000)
* hurd/hurdsig.c (_hurd_internal_post_signal): For SIGNO==0 pending
check, deliver a pending blocked signal if its action might be to
ignore.
* sysdeps/mach/hurd/sigaction.c: If new action is SIG_IGN or SIG_DFL
and SIG is pending, wake up signal thread to check us.

* hurd/hurdsig.c (_hurd_internal_post_signal): Don't mark a signal
pending while blocked or stopped when the action is to ignore it.

* hurd/hurdsig.c (_hurd_internal_post_signal: resume): Only set
SS_SUSPENDED when the thread is really suspended.

* elf/rtld.c (dl_main): Don't dereference _dl_rtld_map.l_next if null.

ChangeLog
elf/rtld.c
hurd/hurdsig.c
sysdeps/mach/hurd/sigaction.c

index 970be16..47cacbd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
+Thu Jun  6 16:12:39 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * hurd/hurdsig.c (_hurd_internal_post_signal): For SIGNO==0 pending
+       check, deliver a pending blocked signal if its action might be to
+       ignore.
+       * sysdeps/mach/hurd/sigaction.c: If new action is SIG_IGN or SIG_DFL
+       and SIG is pending, wake up signal thread to check us.
+
+       * hurd/hurdsig.c (_hurd_internal_post_signal): Don't mark a signal
+       pending while blocked or stopped when the action is to ignore it.
+
 Thu Jun  6 12:56:03 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
+       * hurd/hurdsig.c (_hurd_internal_post_signal: resume): Only set
+       SS_SUSPENDED when the thread is really suspended.
+
+       * elf/rtld.c (dl_main): Don't dereference _dl_rtld_map.l_next if null.
+
        * Makerules (headers): Move append of $(sysdep_headers) after include
        of sysdep makefiles.
 
index 032bb8e..b34d859 100644 (file)
@@ -263,7 +263,8 @@ of this helper program; chances are you did not intend to run this program.\n",
       /* No DT_NEEDED entry referred to the interpreter object itself,
         so remove it from the list of visible objects.  */
       _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next;
-      _dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev;
+      if (_dl_rtld_map.l_next)
+       _dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev;
     }
 
   if (list_only)
index 6abad33..f2bc089 100644 (file)
@@ -516,8 +516,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
                       (vm_address_t) threads,
                       nthreads * sizeof *threads);
       _hurd_stopped = 0;
-      /* The thread that will run the handler is already suspended.  */
-      ss_suspended = 1;
+      if (act == handle)
+       /* The thread that will run the handler is already suspended.  */
+       ss_suspended = 1;
     }
 
   if (signo == 0)
@@ -673,19 +674,11 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
     }
 
   /* Handle receipt of a blocked signal, or any signal while stopped.  */
-  if (__sigismember (&ss->blocked, signo) ||
+  if (act != ignore &&         /* Signals ignored now are forgotten now.  */
+      __sigismember (&ss->blocked, signo) ||
       (signo != SIGKILL && _hurd_stopped))
     {
       mark_pending ();
-      /* If there was a call to resume above in SIGCONT processing
-        and we've left a thread suspended, now's the time to
-        set it going. */
-      if (ss_suspended)
-       {
-         err = __thread_resume (ss->thread);
-         assert_perror (err);
-         ss_suspended = 0;
-       }
       act = ignore;
     }
 
@@ -708,7 +701,15 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
       break;
 
     case ignore:
-      /* Nobody cares about this signal.  */
+      /* Nobody cares about this signal.  If there was a call to resume
+        above in SIGCONT processing and we've left a thread suspended,
+        now's the time to set it going. */
+      if (ss_suspended)
+       {
+         err = __thread_resume (ss->thread);
+         assert_perror (err);
+         ss_suspended = 0;
+       }
       break;
 
     sigbomb:
@@ -904,10 +905,10 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
 
     if (signals_pending ())
       {
-      pending:
        for (signo = 1; signo < NSIG; ++signo)
          if (__sigismember (&pending, signo))
            {
+           deliver:
              __sigdelset (&ss->pending, signo);
              *detail = ss->pending_data[signo];
              __spin_unlock (&ss->lock);
@@ -925,8 +926,15 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
        for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
          {
            __spin_lock (&ss->lock);
-           if (signals_pending ())
-             goto pending;
+           for (signo = 1; signo < NSIG; ++signo)
+             if (__sigismember (&ss->pending, signo) &&
+                 !__sigismember (&ss->blocked, signo) ||
+                 /* We "deliver" immediately pending blocked signals whose
+                     action might be to ignore, so that if ignored they are
+                     dropped right away.  */
+                 ss->actions[signo].sa_handler == SIG_IGN ||
+                 ss->actions[signo].sa_handler == SIG_DFL)
+               goto deliver_pending;
            __spin_unlock (&ss->lock);
          }
        __mutex_unlock (&_hurd_siglock);
index ebe7066..df28131 100644 (file)
@@ -67,6 +67,14 @@ DEFUN(__sigaction, (sig, act, oact),
       __spin_lock (&ss->lock);
       pending = ss->pending & ~ss->blocked;
     }
+  else if (a.sa_handler == SIG_IGN || a.sa_handler == SIG_DFL)
+    /* We are changing to an action that might be to ignore SIG signals.
+       If SIG is blocked and pending and the new action is to ignore it, we
+       must remove it from the pending set now; if the action is changed
+       back and then SIG is unblocked, the signal pending now should not
+       arrive.  So wake up the signal thread to check the new state and do
+       the right thing.  */
+    pending = ss->pending & __sigmask (sig);
   else
     pending = 0;