summaryrefslogtreecommitdiff
path: root/hurd
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-06-06 20:49:22 +0000
committerRoland McGrath <roland@gnu.org>1996-06-06 20:49:22 +0000
commit4d02a5b18a0c2702bfca949bc60187f53d6f39d2 (patch)
treec01194451c8f80184947b404186f744bb84fa9df /hurd
parente60062b76983ec534a6cb2ca77c664e3bc1e29e7 (diff)
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. * 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.
Diffstat (limited to 'hurd')
-rw-r--r--hurd/hurdsig.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 6abad33021..f2bc08993d 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);