1/*
2   Test pending signals
3
4   1. Signals should remain pending while blocked, and not delivered early
5
6   2. When unblocking the signal, the signal should have been delivered
7      by the time sigprocmask syscall is complete.
8 */
9#include <signal.h>
10#include <stdio.h>
11#include <unistd.h>
12#include <stdlib.h>
13#include "config.h"
14
15static volatile int gotsig = 0;
16static volatile int early = 1;
17
18static void handler(int sig)
19{
20	printf("4: got signal %s\n",
21		( sig == SIGUSR1 ? "SIGUSR1" : "unexpected signal" ));
22
23	if (sig != SIGUSR1) {
24		fprintf(stderr, "FAILED: got signal %d instead\n", sig);
25		exit(1);
26	}
27
28	if (early) {
29		fprintf(stderr, "FAILED: signal delivered early (in handler)\n");
30		exit(1);
31	}
32
33	gotsig = 1;
34}
35
36int main()
37{
38	sigset_t all;
39	sigset_t sigusr1;
40
41	sigfillset(&all);
42	sigemptyset(&sigusr1);
43	sigaddset(&sigusr1, SIGUSR1);
44
45	sigprocmask(SIG_BLOCK, &all, NULL);
46
47	signal(SIGUSR1, handler);
48	signal(SIGHUP,  handler);
49
50	printf("1: sending signal\n");
51	kill(getpid(), SIGUSR1);
52	kill(getpid(), SIGHUP);
53
54	printf("2: sleeping\n");
55	sleep(1);
56
57	if (gotsig) {
58		fprintf(stderr, "FAILED: signal delivered too early\n");
59		return 1;
60	}
61
62	printf("3: unblocking\n");
63	early = 0;
64	sigprocmask(SIG_UNBLOCK, &sigusr1, NULL);
65
66	printf("5: unblocked...\n");
67	if (!gotsig) {
68		fprintf(stderr, "FAILED: signal not delivered\n");
69		return 1;
70	}
71
72	printf("6: checking SIGHUP still pending...\n");
73#	if HAVE_SIGWAITINFO
74	{
75		siginfo_t info;
76		if (sigwaitinfo(&all, &info) == -1) {
77			perror("FAILED: sigwaitinfo failed");
78			return 1;
79		}
80		if (info.si_signo != SIGHUP) {
81			fprintf(stderr, "FAILED: SIGHUP not still pending; got signal %d\n",
82				info.si_signo);
83			return 1;
84		}
85	}
86#	endif
87
88	printf("OK\n");
89	return 0;
90}
91