1 /* $OpenBSD: signodefer.c,v 1.3 2003/07/31 21:48:06 deraadt Exp $ */
2 /* PUBLIC DOMAIN Oct 2002 <marc@snafu.org> */
3 
4 /*
5  * test signal delivery of active signals (SA_NODEFER)
6  */
7 
8 #include <signal.h>
9 #include <stdio.h>
10 #include <unistd.h>
11 
12 #include "test.h"
13 
14 volatile sig_atomic_t sigactive;
15 volatile sig_atomic_t sigcount;
16 volatile sig_atomic_t was_active;
17 
18 static void
19 act_handler(int signal, siginfo_t *siginfo, void *context)
20 {
21 	char *str;
22 
23 	/* how many times has the handler been called */
24 	was_active += sigactive++;
25 	sigcount += 1;
26 
27 	/* verify siginfo since we asked for it. */
28 	ASSERT(siginfo != NULL);
29 
30 	asprintf(&str,
31 		 "%sact_handler/%d, signal %d, siginfo %p, context %p\n",
32 		 was_active ? "[recurse] " : "",
33 		 sigcount, signal, siginfo, context);
34 	CHECKe(write(STDOUT_FILENO, str, strlen(str)));
35 	/* Odd times entered send ourself the same signal */
36 	if (sigcount & 1)
37 		CHECKe(kill(getpid(), SIGUSR1));
38 
39 	sigactive = 0;
40 }
41 
42 int
43 main(int argc, char **argv)
44 {
45 	struct sigaction act;
46 
47 	act.sa_sigaction = act_handler;
48 	sigemptyset(&act.sa_mask);
49 	act.sa_flags = SA_SIGINFO;
50 	ASSERT(sigaction(SIGUSR1, &act, NULL) == 0);
51 
52 	/* see if the signal handler recurses */
53 	CHECKe(kill(getpid(), SIGUSR1));
54 	sleep(1);
55         ASSERT(was_active == 0);
56 
57 	/* allow recursive handlers, see that it is handled right */
58 	act.sa_flags |= SA_NODEFER;
59 	ASSERT(sigaction(SIGUSR1, &act, NULL) == 0);
60 
61 	/* see if the signal handler recurses */
62 	CHECKe(kill(getpid(), SIGUSR1));
63 	sleep(1);
64 	ASSERT(was_active == 1);
65 
66 	SUCCEED;
67 }
68