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