summaryrefslogtreecommitdiffstats
path: root/tools/regression/sigqueue/sigqtest2/sigqtest2.c
blob: 078ea81f6278484867d11bf17ab1c25a66c571da (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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* $FreeBSD$ */
#include <signal.h>
#include <stdio.h>
#include <err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

int stop_received;
int exit_received;
int cont_received;

void job_handler(int sig, siginfo_t *si, void *ctx)
{
	int status;
	int ret;

	if (si->si_code == CLD_STOPPED) {
		stop_received = 1;
		kill(si->si_pid, SIGCONT);
	} else if (si->si_code == CLD_EXITED) {
		ret = waitpid(si->si_pid, &status, 0);
		if (ret == -1)
			errx(1, "waitpid");
		if (!WIFEXITED(status))
			errx(1, "!WIFEXITED(status)");
		exit_received = 1;
	} else if (si->si_code == CLD_CONTINUED) {
		cont_received = 1;
	}
}

void job_control_test()
{
	struct sigaction sa;
	pid_t pid;
	int count = 10;

	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_SIGINFO;
	sa.sa_sigaction = job_handler;
	sigaction(SIGCHLD, &sa, NULL);
	stop_received = 0;
	cont_received = 0;
	exit_received = 0;
	pid = fork();
	if (pid == 0) {
		kill(getpid(), SIGSTOP);
		exit(1);
	}

	while (!(cont_received && stop_received && exit_received)) {
		sleep(1);
		if (--count == 0)
			break;
	}
	if (!(cont_received && stop_received && exit_received))
		errx(1, "job signals lost");

	printf("job control test OK.\n");
}

void rtsig_handler(int sig, siginfo_t *si, void *ctx)
{
}

int main()
{
	struct sigaction sa;
	sigset_t set;
	union sigval val;

	/* test job control with empty signal queue */
	job_control_test();

	/* now full fill signal queue in kernel */
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_SIGINFO;
	sa.sa_sigaction = rtsig_handler;
	sigaction(SIGRTMIN, &sa, NULL);
	sigemptyset(&set);
	sigaddset(&set, SIGRTMIN);
	sigprocmask(SIG_BLOCK, &set, NULL);
	val.sival_int = 1;
	while (sigqueue(getpid(), SIGRTMIN, val))
		;

	/* signal queue is fully filled, test the job control again. */
	job_control_test();
	return (0);
}
OpenPOWER on IntegriCloud