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