aboutsummaryrefslogtreecommitdiff
blob: 9d7c528c5e98d7c361e71d50d074efe21116ef3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * Based on zsh's sigsuspend() configure test.  Idea here is:
 *  - set a handler for SIGCHLD
 *  - fork a child
 *  - have parent do sigsuspend() and wait for SIGCHLD
 *  - have child exit notifying the parent
 *
 * If sandbox is mucking with SIGCHLD generation, this will often hang. #289963
 */

#include "tests.h"

static int child;

void handler(int sig) { child = sig; }

int main()
{
	struct sigaction act;
	sigset_t set;

	/* Register the SIGCHLD handler */
	act.sa_handler = &handler;
	sigfillset(&act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGCHLD, &act, 0);

	/* Mask all signals */
	sigfillset(&set);
	sigprocmask(SIG_SETMASK, &set, 0);

	/* Fork the child */
	pid_t pid = fork();
	if (pid == -1)
		abort();

	if (pid == 0) {
		/* Have child just exit to automatically send up SIGCHLD */
		return 0;
	} else {
		/* Have parent enable all signals and wait for SIGCHLD */
		sigemptyset(&set);
		sigsuspend(&set);
		if (child == SIGCHLD)
			return 0;

		printf("signal %s (%i) is not SIGCHLD (%i)\n",
			strsignal(child), child, SIGCHLD);
		return 1;
	}
}