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
act_handler(int signal,siginfo_t * siginfo,void * context)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 *
thread(void * arg)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
main(int argc,char ** argv)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