1*c0166d30Sguenther /* $OpenBSD: pthread_kill.c,v 1.5 2016/05/10 04:04:34 guenther Exp $ */
2780f8468Smarc /* PUBLIC DOMAIN Oct 2002 <marc@snafu.org> */
3780f8468Smarc
4780f8468Smarc /*
5780f8468Smarc * Verify that pthread_kill does the right thing, i.e. the signal
6780f8468Smarc * is delivered to the correct thread and proper signal processing
7780f8468Smarc * is performed.
8780f8468Smarc */
9780f8468Smarc
10780f8468Smarc #include <signal.h>
11780f8468Smarc #include <stdio.h>
12780f8468Smarc #include <unistd.h>
13db3296cfSderaadt #include <stdlib.h>
14780f8468Smarc
15780f8468Smarc #include "test.h"
16780f8468Smarc
17db3296cfSderaadt static void
act_handler(int signal,siginfo_t * siginfo,void * context)18780f8468Smarc act_handler(int signal, siginfo_t *siginfo, void *context)
19780f8468Smarc {
20780f8468Smarc struct sigaction sa;
21*c0166d30Sguenther char buf[200];
22780f8468Smarc
23780f8468Smarc CHECKe(sigaction(SIGUSR1, NULL, &sa));
24780f8468Smarc ASSERT(sa.sa_handler == SIG_DFL);
25780f8468Smarc ASSERT(siginfo != NULL);
26*c0166d30Sguenther snprintf(buf, sizeof buf,
27*c0166d30Sguenther "act_handler: signal %d, siginfo %p, context %p\n",
28780f8468Smarc signal, siginfo, context);
29*c0166d30Sguenther write(STDOUT_FILENO, buf, strlen(buf));
30780f8468Smarc }
31780f8468Smarc
32db3296cfSderaadt static void *
thread(void * arg)33780f8468Smarc thread(void * arg)
34780f8468Smarc {
35780f8468Smarc sigset_t run_mask;
36780f8468Smarc sigset_t suspender_mask;
37780f8468Smarc
38780f8468Smarc /* wait for sigusr1 */
39780f8468Smarc SET_NAME(arg);
40780f8468Smarc
41780f8468Smarc /* Run with all signals blocked, then suspend for SIGUSR1 */
42780f8468Smarc sigfillset(&run_mask);
43780f8468Smarc CHECKe(sigprocmask(SIG_SETMASK, &run_mask, NULL));
44780f8468Smarc sigfillset(&suspender_mask);
45780f8468Smarc sigdelset(&suspender_mask, SIGUSR1);
46780f8468Smarc for (;;) {
47780f8468Smarc sigsuspend(&suspender_mask);
48780f8468Smarc ASSERT(errno == EINTR);
49780f8468Smarc printf("Thread %s woke up\n", (char*) arg);
50780f8468Smarc }
51780f8468Smarc
52780f8468Smarc }
53780f8468Smarc
54780f8468Smarc int
main(int argc,char ** argv)55780f8468Smarc main(int argc, char **argv)
56780f8468Smarc {
57780f8468Smarc pthread_t thread1;
58780f8468Smarc pthread_t thread2;
59780f8468Smarc struct sigaction act;
60780f8468Smarc
61780f8468Smarc act.sa_sigaction = act_handler;
62780f8468Smarc sigemptyset(&act.sa_mask);
63780f8468Smarc act.sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER;
64780f8468Smarc CHECKe(sigaction(SIGUSR1, &act, NULL));
65780f8468Smarc CHECKr(pthread_create(&thread1, NULL, thread, "T1"));
66780f8468Smarc CHECKr(pthread_create(&thread2, NULL, thread, "T2"));
67780f8468Smarc sleep(1);
68780f8468Smarc
69780f8468Smarc /* Signal handler should run once, both threads should awaken */
70780f8468Smarc CHECKe(kill(getpid(), SIGUSR1));
71780f8468Smarc sleep(1);
72780f8468Smarc
73780f8468Smarc /* Signal handler run once, only T1 should awaken */
74780f8468Smarc CHECKe(sigaction(SIGUSR1, &act, NULL));
75780f8468Smarc CHECKr(pthread_kill(thread1, SIGUSR1));
76780f8468Smarc sleep(1);
77780f8468Smarc
78780f8468Smarc /* Signal handler run once, only T2 should awaken */
79780f8468Smarc CHECKe(sigaction(SIGUSR1, &act, NULL));
80780f8468Smarc CHECKr(pthread_kill(thread2, SIGUSR1));
81780f8468Smarc sleep(1);
82780f8468Smarc
83780f8468Smarc SUCCEED;
84780f8468Smarc }
85