diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | elf/rtld.c | 3 | ||||
-rw-r--r-- | hurd/hurdsig.c | 40 | ||||
-rw-r--r-- | sysdeps/mach/hurd/sigaction.c | 8 |
4 files changed, 50 insertions, 17 deletions
@@ -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. @@ -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) diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index 6abad33..f2bc089 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -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); diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c index ebe7066..df28131 100644 --- a/sysdeps/mach/hurd/sigaction.c +++ b/sysdeps/mach/hurd/sigaction.c @@ -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; |