1 /* $OpenBSD: pthread_kill.c,v 1.5 2016/05/10 04:04:34 guenther Exp $ */ 2 /* PUBLIC DOMAIN Oct 2002 <marc@snafu.org> */ 3 4 /* 5 * Verify that pthread_kill does the right thing, i.e. the signal 6 * is delivered to the correct thread and proper signal processing 7 * is performed. 8 */ 9 10 #include <signal.h> 11 #include <stdio.h> 12 #include <unistd.h> 13 #include <stdlib.h> 14 15 #include "test.h" 16 17 static void 18 act_handler(int signal, siginfo_t *siginfo, void *context) 19 { 20 struct sigaction sa; 21 char buf[200]; 22 23 CHECKe(sigaction(SIGUSR1, NULL, &sa)); 24 ASSERT(sa.sa_handler == SIG_DFL); 25 ASSERT(siginfo != NULL); 26 snprintf(buf, sizeof buf, 27 "act_handler: signal %d, siginfo %p, context %p\n", 28 signal, siginfo, context); 29 write(STDOUT_FILENO, buf, strlen(buf)); 30 } 31 32 static void * 33 thread(void * arg) 34 { 35 sigset_t run_mask; 36 sigset_t suspender_mask; 37 38 /* wait for sigusr1 */ 39 SET_NAME(arg); 40 41 /* Run with all signals blocked, then suspend for SIGUSR1 */ 42 sigfillset(&run_mask); 43 CHECKe(sigprocmask(SIG_SETMASK, &run_mask, NULL)); 44 sigfillset(&suspender_mask); 45 sigdelset(&suspender_mask, SIGUSR1); 46 for (;;) { 47 sigsuspend(&suspender_mask); 48 ASSERT(errno == EINTR); 49 printf("Thread %s woke up\n", (char*) arg); 50 } 51 52 } 53 54 int 55 main(int argc, char **argv) 56 { 57 pthread_t thread1; 58 pthread_t thread2; 59 struct sigaction act; 60 61 act.sa_sigaction = act_handler; 62 sigemptyset(&act.sa_mask); 63 act.sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER; 64 CHECKe(sigaction(SIGUSR1, &act, NULL)); 65 CHECKr(pthread_create(&thread1, NULL, thread, "T1")); 66 CHECKr(pthread_create(&thread2, NULL, thread, "T2")); 67 sleep(1); 68 69 /* Signal handler should run once, both threads should awaken */ 70 CHECKe(kill(getpid(), SIGUSR1)); 71 sleep(1); 72 73 /* Signal handler run once, only T1 should awaken */ 74 CHECKe(sigaction(SIGUSR1, &act, NULL)); 75 CHECKr(pthread_kill(thread1, SIGUSR1)); 76 sleep(1); 77 78 /* Signal handler run once, only T2 should awaken */ 79 CHECKe(sigaction(SIGUSR1, &act, NULL)); 80 CHECKr(pthread_kill(thread2, SIGUSR1)); 81 sleep(1); 82 83 SUCCEED; 84 } 85