xref: /freebsd/tools/regression/sigqueue/sigqtest2/sigqtest2.c (revision eb9de28f2018d17997a4d83d3a303bb7e4c10f4c)
114b7815fSDavid Xu /* $FreeBSD$ */
214b7815fSDavid Xu #include <sys/types.h>
314b7815fSDavid Xu #include <sys/wait.h>
4eb9de28fSKonstantin Belousov #include <err.h>
5eb9de28fSKonstantin Belousov #include <errno.h>
6eb9de28fSKonstantin Belousov #include <signal.h>
7eb9de28fSKonstantin Belousov #include <stdio.h>
8eb9de28fSKonstantin Belousov #include <stdlib.h>
9eb9de28fSKonstantin Belousov #include <unistd.h>
1014b7815fSDavid Xu 
1114b7815fSDavid Xu int stop_received;
1214b7815fSDavid Xu int exit_received;
1314b7815fSDavid Xu int cont_received;
1414b7815fSDavid Xu 
15eb9de28fSKonstantin Belousov void
16eb9de28fSKonstantin Belousov job_handler(int sig, siginfo_t *si, void *ctx)
1714b7815fSDavid Xu {
1814b7815fSDavid Xu 	int status;
1914b7815fSDavid Xu 	int ret;
2014b7815fSDavid Xu 
2114b7815fSDavid Xu 	if (si->si_code == CLD_STOPPED) {
22eb9de28fSKonstantin Belousov 		printf("%d: stop received\n", si->si_pid);
2314b7815fSDavid Xu 		stop_received = 1;
2414b7815fSDavid Xu 		kill(si->si_pid, SIGCONT);
2514b7815fSDavid Xu 	} else if (si->si_code == CLD_EXITED) {
26eb9de28fSKonstantin Belousov 		printf("%d: exit received\n", si->si_pid);
2714b7815fSDavid Xu 		ret = waitpid(si->si_pid, &status, 0);
2814b7815fSDavid Xu 		if (ret == -1)
2914b7815fSDavid Xu 			errx(1, "waitpid");
3014b7815fSDavid Xu 		if (!WIFEXITED(status))
3114b7815fSDavid Xu 			errx(1, "!WIFEXITED(status)");
3214b7815fSDavid Xu 		exit_received = 1;
3314b7815fSDavid Xu 	} else if (si->si_code == CLD_CONTINUED) {
34eb9de28fSKonstantin Belousov 		printf("%d: cont received\n", si->si_pid);
3514b7815fSDavid Xu 		cont_received = 1;
3614b7815fSDavid Xu 	}
3714b7815fSDavid Xu }
3814b7815fSDavid Xu 
39eb9de28fSKonstantin Belousov void
40eb9de28fSKonstantin Belousov job_control_test(void)
4114b7815fSDavid Xu {
4214b7815fSDavid Xu 	struct sigaction sa;
4314b7815fSDavid Xu 	pid_t pid;
4414b7815fSDavid Xu 	int count = 10;
4514b7815fSDavid Xu 
4614b7815fSDavid Xu 	sigemptyset(&sa.sa_mask);
4714b7815fSDavid Xu 	sa.sa_flags = SA_SIGINFO;
4814b7815fSDavid Xu 	sa.sa_sigaction = job_handler;
4914b7815fSDavid Xu 	sigaction(SIGCHLD, &sa, NULL);
5014b7815fSDavid Xu 	stop_received = 0;
5114b7815fSDavid Xu 	cont_received = 0;
5214b7815fSDavid Xu 	exit_received = 0;
53eb9de28fSKonstantin Belousov 	fflush(stdout);
5414b7815fSDavid Xu 	pid = fork();
5514b7815fSDavid Xu 	if (pid == 0) {
56eb9de28fSKonstantin Belousov 		printf("child %d\n", getpid());
5714b7815fSDavid Xu 		kill(getpid(), SIGSTOP);
58eb9de28fSKonstantin Belousov 		sleep(2);
5914b7815fSDavid Xu 		exit(1);
6014b7815fSDavid Xu 	}
6114b7815fSDavid Xu 
6214b7815fSDavid Xu 	while (!(cont_received && stop_received && exit_received)) {
6314b7815fSDavid Xu 		sleep(1);
6414b7815fSDavid Xu 		if (--count == 0)
6514b7815fSDavid Xu 			break;
6614b7815fSDavid Xu 	}
6714b7815fSDavid Xu 	if (!(cont_received && stop_received && exit_received))
6814b7815fSDavid Xu 		errx(1, "job signals lost");
6914b7815fSDavid Xu 
7014b7815fSDavid Xu 	printf("job control test OK.\n");
7114b7815fSDavid Xu }
7214b7815fSDavid Xu 
73eb9de28fSKonstantin Belousov void
74eb9de28fSKonstantin Belousov rtsig_handler(int sig, siginfo_t *si, void *ctx)
7514b7815fSDavid Xu {
7614b7815fSDavid Xu }
7714b7815fSDavid Xu 
78eb9de28fSKonstantin Belousov int
79eb9de28fSKonstantin Belousov main()
8014b7815fSDavid Xu {
8114b7815fSDavid Xu 	struct sigaction sa;
8214b7815fSDavid Xu 	sigset_t set;
8314b7815fSDavid Xu 	union sigval val;
8414b7815fSDavid Xu 
8514b7815fSDavid Xu 	/* test job control with empty signal queue */
8614b7815fSDavid Xu 	job_control_test();
8714b7815fSDavid Xu 
8814b7815fSDavid Xu 	/* now full fill signal queue in kernel */
8914b7815fSDavid Xu 	sigemptyset(&sa.sa_mask);
9014b7815fSDavid Xu 	sa.sa_flags = SA_SIGINFO;
9114b7815fSDavid Xu 	sa.sa_sigaction = rtsig_handler;
9214b7815fSDavid Xu 	sigaction(SIGRTMIN, &sa, NULL);
9314b7815fSDavid Xu 	sigemptyset(&set);
9414b7815fSDavid Xu 	sigaddset(&set, SIGRTMIN);
9514b7815fSDavid Xu 	sigprocmask(SIG_BLOCK, &set, NULL);
9614b7815fSDavid Xu 	val.sival_int = 1;
9714b7815fSDavid Xu 	while (sigqueue(getpid(), SIGRTMIN, val))
9814b7815fSDavid Xu 		;
9914b7815fSDavid Xu 
10014b7815fSDavid Xu 	/* signal queue is fully filled, test the job control again. */
10114b7815fSDavid Xu 	job_control_test();
10214b7815fSDavid Xu 	return (0);
10314b7815fSDavid Xu }
104