1 /* $OpenBSD: uthread_kill.c,v 1.11 2003/04/30 17:54:17 marc Exp $ */ 2 /* PUBLIC_DOMAIN <marc@snafu.org> */ 3 4 #include <errno.h> 5 #include <signal.h> 6 #include <string.h> 7 #include <unistd.h> 8 #ifdef _THREAD_SAFE 9 #include <pthread.h> 10 11 #include "pthread_private.h" 12 13 /* 14 * Fake up a minimal siginfo_t for the given signal unless one is already 15 * pending. The signal number is assumed to be valid. 16 */ 17 void _thread_kill_siginfo(int sig)18_thread_kill_siginfo(int sig) 19 { 20 struct sigstatus *ss = &_thread_sigq[sig - 1]; 21 22 _SPINLOCK(&ss->lock); 23 if (ss->pending == 0) { 24 ss->pending = 1; 25 memset(&ss->siginfo, 0, sizeof ss->siginfo); 26 ss->siginfo.si_signo = sig; 27 ss->siginfo.si_code = SI_USER; 28 ss->siginfo.si_errno = errno; 29 ss->siginfo.si_pid = getpid(); 30 } 31 _SPINUNLOCK(&ss->lock); 32 } 33 34 /* 35 * Validate the signal number and thread. If valid process the signal. 36 */ 37 int pthread_kill(pthread_t pthread,int sig)38pthread_kill(pthread_t pthread, int sig) 39 { 40 int ret; 41 42 if (sig >= 0 && sig < NSIG) { 43 ret = _find_thread(pthread); 44 if (sig != 0) { 45 if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { 46 _thread_kern_sig_defer(); 47 if (pthread->state == PS_SIGWAIT && 48 sigismember(pthread->data.sigwait, sig)) { 49 PTHREAD_NEW_STATE(pthread,PS_RUNNING); 50 pthread->signo = sig; 51 } else { 52 _thread_kill_siginfo(sig); 53 _thread_signal(pthread,sig); 54 } 55 _thread_kern_sig_undefer(); 56 } 57 } 58 } else 59 ret = EINVAL; 60 61 return ret; 62 } 63 #endif 64