123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- #include <errno.h>
- #include <signal.h>
- #include "pthread.h"
- #include "internals.h"
- #include "spinlock.h"
- #include <ucontext.h>
- extern __typeof(sigaction) __libc_sigaction;
- int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask)
- {
- sigset_t mask;
- if (newmask != NULL) {
- mask = *newmask;
-
- switch(how) {
- case SIG_SETMASK:
- sigaddset(&mask, __pthread_sig_restart);
- sigdelset(&mask, __pthread_sig_cancel);
- if (__pthread_sig_debug > 0)
- sigdelset(&mask, __pthread_sig_debug);
- break;
- case SIG_BLOCK:
- sigdelset(&mask, __pthread_sig_cancel);
- if (__pthread_sig_debug > 0)
- sigdelset(&mask, __pthread_sig_debug);
- break;
- case SIG_UNBLOCK:
- sigdelset(&mask, __pthread_sig_restart);
- break;
- }
- newmask = &mask;
- }
- if (sigprocmask(how, newmask, oldmask) == -1)
- return errno;
- else
- return 0;
- }
- int pthread_kill(pthread_t thread, int signo)
- {
- pthread_handle handle = thread_handle(thread);
- int pid;
- __pthread_lock(&handle->h_lock, NULL);
- if (invalid_handle(handle, thread)) {
- __pthread_unlock(&handle->h_lock);
- return ESRCH;
- }
- pid = handle->h_descr->p_pid;
- __pthread_unlock(&handle->h_lock);
- if (kill(pid, signo) == -1)
- return errno;
- else
- return 0;
- }
- union sighandler __sighandler[NSIG] =
- { [1 ... NSIG - 1] = { (arch_sighandler_t) SIG_ERR } };
- int __pthread_sigaction(int sig, const struct sigaction * act,
- struct sigaction * oact)
- {
- struct sigaction newact;
- struct sigaction *newactp;
- __sighandler_t old = SIG_DFL;
- if (sig == __pthread_sig_restart ||
- sig == __pthread_sig_cancel ||
- (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
- {
- __set_errno (EINVAL);
- return -1;
- }
- if (sig > 0 && sig < NSIG)
- old = (__sighandler_t) __sighandler[sig].old;
- if (act)
- {
- newact = *act;
- if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL
- && sig > 0 && sig < NSIG)
- {
- if (act->sa_flags & SA_SIGINFO)
- newact.sa_handler = (__sighandler_t) __pthread_sighandler_rt;
- else
- newact.sa_handler = (__sighandler_t) __pthread_sighandler;
- if (old == SIG_IGN || old == SIG_DFL || old == SIG_ERR)
- __sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
- }
- newactp = &newact;
- }
- else
- newactp = NULL;
- if (__libc_sigaction(sig, newactp, oact) == -1)
- {
- if (act)
- __sighandler[sig].old = (arch_sighandler_t) old;
- return -1;
- }
- if (sig > 0 && sig < NSIG)
- {
- if (oact != NULL
-
- && old != SIG_ERR)
- oact->sa_handler = old;
- if (act)
-
- __sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
- }
- return 0;
- }
- #ifdef SHARED
- strong_alias(__pthread_sigaction, __sigaction)
- strong_alias(__pthread_sigaction, sigaction)
- #endif
- int __pthread_sigwait(const sigset_t * set, int * sig)
- {
- __volatile__ pthread_descr self = thread_self();
- sigset_t mask;
- int s;
- sigjmp_buf jmpbuf;
- struct sigaction sa;
-
- __sigfillset(&mask);
- sigdelset(&mask, __pthread_sig_cancel);
- for (s = 1; s < NSIG; s++) {
- if (sigismember(set, s) &&
- s != __pthread_sig_restart &&
- 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;
- __sigfillset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(s, &sa, NULL);
- }
- }
- }
-
- if (sigsetjmp(jmpbuf, 1) == 0) {
- THREAD_SETMEM(self, p_cancel_jmp, &jmpbuf);
- if (! (THREAD_GETMEM(self, p_canceled)
- && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) {
-
- THREAD_SETMEM(self, p_signal, 0);
-
- THREAD_SETMEM(self, p_sigwaiting, 1);
-
- sigsuspend(&mask);
- }
- }
- THREAD_SETMEM(self, p_cancel_jmp, NULL);
-
- pthread_testcancel();
-
- *sig = THREAD_GETMEM(self, p_signal);
- return 0;
- }
- #ifdef SHARED
- strong_alias (__pthread_sigwait, sigwait)
- #endif
- int __pthread_raise (int sig)
- {
- int retcode = pthread_kill(pthread_self(), sig);
- if (retcode == 0)
- return 0;
- else {
- errno = retcode;
- return -1;
- }
- }
- #ifdef SHARED
- strong_alias (__pthread_raise, raise)
- #endif
- LIBC_CANCEL_HANDLED ();
|