xref: /freebsd/tools/regression/sigqueue/sigqtest2/sigqtest2.c (revision 282a3889ebf826db9839be296ff1dd903f6d6d6e)
1 /* $FreeBSD$ */
2 #include <signal.h>
3 #include <stdio.h>
4 #include <err.h>
5 #include <errno.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 
9 int stop_received;
10 int exit_received;
11 int cont_received;
12 
13 void job_handler(int sig, siginfo_t *si, void *ctx)
14 {
15 	int status;
16 	int ret;
17 
18 	if (si->si_code == CLD_STOPPED) {
19 		stop_received = 1;
20 		kill(si->si_pid, SIGCONT);
21 	} else if (si->si_code == CLD_EXITED) {
22 		ret = waitpid(si->si_pid, &status, 0);
23 		if (ret == -1)
24 			errx(1, "waitpid");
25 		if (!WIFEXITED(status))
26 			errx(1, "!WIFEXITED(status)");
27 		exit_received = 1;
28 	} else if (si->si_code == CLD_CONTINUED) {
29 		cont_received = 1;
30 	}
31 }
32 
33 void job_control_test()
34 {
35 	struct sigaction sa;
36 	pid_t pid;
37 	int count = 10;
38 
39 	sigemptyset(&sa.sa_mask);
40 	sa.sa_flags = SA_SIGINFO;
41 	sa.sa_sigaction = job_handler;
42 	sigaction(SIGCHLD, &sa, NULL);
43 	stop_received = 0;
44 	cont_received = 0;
45 	exit_received = 0;
46 	pid = fork();
47 	if (pid == 0) {
48 		kill(getpid(), SIGSTOP);
49 		exit(1);
50 	}
51 
52 	while (!(cont_received && stop_received && exit_received)) {
53 		sleep(1);
54 		if (--count == 0)
55 			break;
56 	}
57 	if (!(cont_received && stop_received && exit_received))
58 		errx(1, "job signals lost");
59 
60 	printf("job control test OK.\n");
61 }
62 
63 void rtsig_handler(int sig, siginfo_t *si, void *ctx)
64 {
65 }
66 
67 int main()
68 {
69 	struct sigaction sa;
70 	sigset_t set;
71 	union sigval val;
72 
73 	/* test job control with empty signal queue */
74 	job_control_test();
75 
76 	/* now full fill signal queue in kernel */
77 	sigemptyset(&sa.sa_mask);
78 	sa.sa_flags = SA_SIGINFO;
79 	sa.sa_sigaction = rtsig_handler;
80 	sigaction(SIGRTMIN, &sa, NULL);
81 	sigemptyset(&set);
82 	sigaddset(&set, SIGRTMIN);
83 	sigprocmask(SIG_BLOCK, &set, NULL);
84 	val.sival_int = 1;
85 	while (sigqueue(getpid(), SIGRTMIN, val))
86 		;
87 
88 	/* signal queue is fully filled, test the job control again. */
89 	job_control_test();
90 	return (0);
91 }
92