1 /* $OpenBSD: siginterrupt.c,v 1.1 2011/09/13 23:50:17 fgsch Exp $ */
2 /*
3 * Federico G. Schwindt <fgsch@openbsd.org>, 2011. Public Domain.
4 */
5 #include <pthread.h>
6 #include <signal.h>
7 #include <unistd.h>
8 #include "test.h"
9
10 volatile sig_atomic_t hits = 0;
11
12 void
handler(int sig)13 handler(int sig)
14 {
15 hits++;
16 }
17
18 void *
blocker(void * arg)19 blocker(void *arg)
20 {
21 int fds[2];
22 char buf;
23
24 CHECKe(pipe(fds));
25 ASSERT(read(fds[0], &buf, 1) == -1);
26 return ((caddr_t)NULL + errno);
27 }
28
29 int
main(int argc,char ** argv)30 main(int argc, char **argv)
31 {
32 pthread_t tid;
33 void *retval;
34
35 ASSERT(signal(SIGUSR1, handler) != SIG_ERR);
36
37 CHECKr(pthread_create(&tid, NULL, blocker, NULL));
38 sleep(1);
39
40 /* With signal(3) system calls will be restarted. */
41 CHECKr(pthread_kill(tid, SIGUSR1));
42 sleep(1);
43
44 /* Same as default with signal(3). */
45 CHECKe(siginterrupt(SIGUSR1, 0));
46 CHECKr(pthread_kill(tid, SIGUSR1));
47 sleep(1);
48
49 /* Should interrupt the call now. */
50 CHECKe(siginterrupt(SIGUSR1, 1));
51 CHECKr(pthread_kill(tid, SIGUSR1));
52 sleep(1);
53
54 CHECKr(pthread_join(tid, &retval));
55 ASSERT(retval == (void *)EINTR);
56 ASSERT(hits == 3);
57 SUCCEED;
58 }
59