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
14volatile sig_atomic_t sigactive;
15volatile sig_atomic_t sigcount;
16volatile sig_atomic_t was_active;
17
18static void
19act_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
42int
43main(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