diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 9 | ||||
-rw-r--r-- | linuxthreads/Makefile | 5 | ||||
-rw-r--r-- | linuxthreads/internals.h | 19 | ||||
-rw-r--r-- | linuxthreads/sighandler.c | 69 | ||||
-rw-r--r-- | linuxthreads/signals.c | 79 |
5 files changed, 112 insertions, 69 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 747e409521..9a58488838 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,12 @@ +2002-05-03 Ulrich Drepper <drepper@redhat.com> + + * signals.c: Move sighandler functions to... + * sighandler.c: ...here. New file. + * signals.c: Move signal handler related type definitions to... + * internals.h: ...here. Add prototypes for signal handlers. + * Makefile (libpthread-routines): Add sighandler. + (CFLAGS-sighandler.c): Add $(exceptions). + 2002-04-30 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/x86_64/Makefile: New file. diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile index 33c041ebc5..41432846c7 100644 --- a/linuxthreads/Makefile +++ b/linuxthreads/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ libpthread-routines := attr cancel condvar join manager mutex ptfork \ ptlongjmp pthread signals specific errno lockfile \ semaphore spinlock wrapsyscall rwlock pt-machine \ oldsemaphore events getcpuclockid pspinlock barrier \ - ptclock_gettime ptclock_settime + ptclock_gettime ptclock_settime sighandler nodelete-yes = -Wl,--enable-new-dtags,-z,nodelete initfirst-yes = -Wl,--enable-new-dtags,-z,initfirst @@ -80,6 +80,7 @@ CFLAGS-pthread.c += -D__NO_WEAK_PTHREAD_ALIASES $(znodelete-$(have-z-nodelete)) CFLAGS-ptfork.c += -D__NO_WEAK_PTHREAD_ALIASES CFLAGS-cancel.c += -D__NO_WEAK_PTHREAD_ALIASES -D_RPC_THREAD_SAFE_ CFLAGS-unload.c += -DPREFIX=\"$(objpfx)\" +CFLAGS-sighandler.c += $(exceptions) # Depend on libc.so so a DT_NEEDED is generated in the shared objects. # This ensures they will load libc.so for needed symbols if loaded by diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h index 45a73ad194..39c545c5e1 100644 --- a/linuxthreads/internals.h +++ b/linuxthreads/internals.h @@ -20,8 +20,10 @@ /* Includes */ #include <limits.h> +#include <signal.h> #include <unistd.h> #include <stackinfo.h> +#include <sigcontextinfo.h> #include <tls.h> #include "descr.h" @@ -93,6 +95,16 @@ struct pthread_request { }; + +typedef void (*arch_sighandler_t) (int, SIGCONTEXT); +union sighandler +{ + arch_sighandler_t old; + void (*rt) (int, struct siginfo *, struct ucontext *); +}; +extern union sighandler __sighandler[NSIG]; + + /* Signals used for suspend/restart and for cancellation notification. */ extern int __pthread_sig_restart; @@ -367,4 +379,11 @@ extern void __linuxthreads_reap_event (void); /* This function is called to initialize the pthread library. */ extern void __pthread_initialize (void); + +/* Sighandler wrappers. */ +extern void __pthread_sighandler(int signo, SIGCONTEXT ctx); +extern void __pthread_sighandler_rt(int signo, struct siginfo *si, + struct ucontext *uc); +extern void __pthread_null_sighandler(int sig); + #endif /* internals.h */ diff --git a/linuxthreads/sighandler.c b/linuxthreads/sighandler.c new file mode 100644 index 0000000000..ab8b38e539 --- /dev/null +++ b/linuxthreads/sighandler.c @@ -0,0 +1,69 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Signal handlers */ + +#include "internals.h" + + +/* The wrapper around user-provided signal handlers */ +void __pthread_sighandler(int signo, SIGCONTEXT ctx) +{ + pthread_descr self; + char * in_sighandler; + self = thread_self(); + /* If we're in a sigwait operation, just record the signal received + and return without calling the user's handler */ + if (THREAD_GETMEM(self, p_sigwaiting)) { + THREAD_SETMEM(self, p_sigwaiting, 0); + THREAD_SETMEM(self, p_signal, signo); + return; + } + /* Record that we're in a signal handler and call the user's + handler function */ + in_sighandler = THREAD_GETMEM(self, p_in_sighandler); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME); + CALL_SIGHANDLER(__sighandler[signo].old, signo, ctx); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, NULL); +} + +/* The same, this time for real-time signals. */ +void __pthread_sighandler_rt(int signo, struct siginfo *si, + struct ucontext *uc) +{ + pthread_descr self; + char * in_sighandler; + self = thread_self(); + /* If we're in a sigwait operation, just record the signal received + and return without calling the user's handler */ + if (THREAD_GETMEM(self, p_sigwaiting)) { + THREAD_SETMEM(self, p_sigwaiting, 0); + THREAD_SETMEM(self, p_signal, signo); + return; + } + /* Record that we're in a signal handler and call the user's + handler function */ + in_sighandler = THREAD_GETMEM(self, p_in_sighandler); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME); + __sighandler[signo].rt(signo, si, uc); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, NULL); +} + + +/* A signal handler that does nothing */ +void __pthread_null_sighandler(int sig) { } diff --git a/linuxthreads/signals.c b/linuxthreads/signals.c index da3ce69a4d..a11f865e73 100644 --- a/linuxthreads/signals.c +++ b/linuxthreads/signals.c @@ -20,7 +20,7 @@ #include "internals.h" #include "spinlock.h" #include <ucontext.h> -#include <sigcontextinfo.h> + int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask) { @@ -68,60 +68,8 @@ int pthread_kill(pthread_t thread, int signo) return 0; } -/* User-provided signal handlers */ -typedef void (*arch_sighandler_t) (int, SIGCONTEXT); -static union -{ - arch_sighandler_t old; - void (*rt) (int, struct siginfo *, struct ucontext *); -} sighandler[NSIG] = { [1 ... NSIG - 1] = { (arch_sighandler_t) SIG_ERR } }; - -/* The wrapper around user-provided signal handlers */ -static void pthread_sighandler(int signo, SIGCONTEXT ctx) -{ - pthread_descr self; - char * in_sighandler; - self = thread_self(); - /* If we're in a sigwait operation, just record the signal received - and return without calling the user's handler */ - if (THREAD_GETMEM(self, p_sigwaiting)) { - THREAD_SETMEM(self, p_sigwaiting, 0); - THREAD_SETMEM(self, p_signal, signo); - return; - } - /* Record that we're in a signal handler and call the user's - handler function */ - in_sighandler = THREAD_GETMEM(self, p_in_sighandler); - if (in_sighandler == NULL) - THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME); - CALL_SIGHANDLER(sighandler[signo].old, signo, ctx); - if (in_sighandler == NULL) - THREAD_SETMEM(self, p_in_sighandler, NULL); -} - -/* The same, this time for real-time signals. */ -static void pthread_sighandler_rt(int signo, struct siginfo *si, - struct ucontext *uc) -{ - pthread_descr self; - char * in_sighandler; - self = thread_self(); - /* If we're in a sigwait operation, just record the signal received - and return without calling the user's handler */ - if (THREAD_GETMEM(self, p_sigwaiting)) { - THREAD_SETMEM(self, p_sigwaiting, 0); - THREAD_SETMEM(self, p_signal, signo); - return; - } - /* Record that we're in a signal handler and call the user's - handler function */ - in_sighandler = THREAD_GETMEM(self, p_in_sighandler); - if (in_sighandler == NULL) - THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME); - sighandler[signo].rt(signo, si, uc); - if (in_sighandler == NULL) - THREAD_SETMEM(self, p_in_sighandler, NULL); -} +union sighandler __sighandler[NSIG] = + { [1 ... NSIG - 1] = { (arch_sighandler_t) SIG_ERR } }; /* The wrapper around sigaction. Install our own signal handler around the signal. */ @@ -145,9 +93,9 @@ int __sigaction(int sig, const struct sigaction * act, && sig > 0 && sig < NSIG) { if (act->sa_flags & SA_SIGINFO) - newact.sa_handler = (__sighandler_t) pthread_sighandler_rt; + newact.sa_handler = (__sighandler_t) __pthread_sighandler_rt; else - newact.sa_handler = (__sighandler_t) pthread_sighandler; + newact.sa_handler = (__sighandler_t) __pthread_sighandler; } newactp = &newact; } @@ -161,20 +109,17 @@ int __sigaction(int sig, const struct sigaction * act, /* We may have inherited SIG_IGN from the parent, so return the kernel's idea of the signal handler the first time through. */ - && (__sighandler_t) sighandler[sig].old != SIG_ERR) - oact->sa_handler = (__sighandler_t) sighandler[sig].old; + && (__sighandler_t) __sighandler[sig].old != SIG_ERR) + oact->sa_handler = (__sighandler_t) __sighandler[sig].old; if (act) /* For the assignment it does not matter whether it's a normal or real-time signal. */ - sighandler[sig].old = (arch_sighandler_t) act->sa_handler; + __sighandler[sig].old = (arch_sighandler_t) act->sa_handler; } return 0; } strong_alias(__sigaction, sigaction) -/* A signal handler that does nothing */ -static void pthread_null_sighandler(int sig) { } - /* sigwait -- synchronously wait for a signal */ int sigwait(const sigset_t * set, int * sig) { @@ -198,10 +143,10 @@ int sigwait(const sigset_t * set, int * sig) s != __pthread_sig_cancel && s != __pthread_sig_debug) { sigdelset(&mask, s); - if (sighandler[s].old == (arch_sighandler_t) SIG_ERR || - sighandler[s].old == (arch_sighandler_t) SIG_DFL || - sighandler[s].old == (arch_sighandler_t) SIG_IGN) { - sa.sa_handler = pthread_null_sighandler; + if (__sighandler[s].old == (arch_sighandler_t) SIG_ERR || + __sighandler[s].old == (arch_sighandler_t) SIG_DFL || + __sighandler[s].old == (arch_sighandler_t) SIG_IGN) { + sa.sa_handler = __pthread_null_sighandler; sigfillset(&sa.sa_mask); sa.sa_flags = 0; sigaction(s, &sa, NULL); |