xref: /freebsd/tools/regression/sigqueue/sigqtest2/sigqtest2.c (revision 14b7815fcbbca222b20f22a580ca0b4c75679aba)
114b7815fSDavid Xu /* $FreeBSD$ */
214b7815fSDavid Xu #include <signal.h>
314b7815fSDavid Xu #include <stdio.h>
414b7815fSDavid Xu #include <err.h>
514b7815fSDavid Xu #include <errno.h>
614b7815fSDavid Xu #include <sys/types.h>
714b7815fSDavid Xu #include <sys/wait.h>
814b7815fSDavid Xu 
914b7815fSDavid Xu int stop_received;
1014b7815fSDavid Xu int exit_received;
1114b7815fSDavid Xu int cont_received;
1214b7815fSDavid Xu 
1314b7815fSDavid Xu void job_handler(int sig, siginfo_t *si, void *ctx)
1414b7815fSDavid Xu {
1514b7815fSDavid Xu 	int status;
1614b7815fSDavid Xu 	int ret;
1714b7815fSDavid Xu 
1814b7815fSDavid Xu 	if (si->si_code == CLD_STOPPED) {
1914b7815fSDavid Xu 		stop_received = 1;
2014b7815fSDavid Xu 		kill(si->si_pid, SIGCONT);
2114b7815fSDavid Xu 	} else if (si->si_code == CLD_EXITED) {
2214b7815fSDavid Xu 		ret = waitpid(si->si_pid, &status, 0);
2314b7815fSDavid Xu 		if (ret == -1)
2414b7815fSDavid Xu 			errx(1, "waitpid");
2514b7815fSDavid Xu 		if (!WIFEXITED(status))
2614b7815fSDavid Xu 			errx(1, "!WIFEXITED(status)");
2714b7815fSDavid Xu 		exit_received = 1;
2814b7815fSDavid Xu 	} else if (si->si_code == CLD_CONTINUED) {
2914b7815fSDavid Xu 		cont_received = 1;
3014b7815fSDavid Xu 	}
3114b7815fSDavid Xu }
3214b7815fSDavid Xu 
3314b7815fSDavid Xu void job_control_test()
3414b7815fSDavid Xu {
3514b7815fSDavid Xu 	struct sigaction sa;
3614b7815fSDavid Xu 	pid_t pid;
3714b7815fSDavid Xu 	int count = 10;
3814b7815fSDavid Xu 
3914b7815fSDavid Xu 	sigemptyset(&sa.sa_mask);
4014b7815fSDavid Xu 	sa.sa_flags = SA_SIGINFO;
4114b7815fSDavid Xu 	sa.sa_sigaction = job_handler;
4214b7815fSDavid Xu 	sigaction(SIGCHLD, &sa, NULL);
4314b7815fSDavid Xu 	stop_received = 0;
4414b7815fSDavid Xu 	cont_received = 0;
4514b7815fSDavid Xu 	exit_received = 0;
4614b7815fSDavid Xu 	pid = fork();
4714b7815fSDavid Xu 	if (pid == 0) {
4814b7815fSDavid Xu 		kill(getpid(), SIGSTOP);
4914b7815fSDavid Xu 		exit(1);
5014b7815fSDavid Xu 	}
5114b7815fSDavid Xu 
5214b7815fSDavid Xu 	while (!(cont_received && stop_received && exit_received)) {
5314b7815fSDavid Xu 		sleep(1);
5414b7815fSDavid Xu 		if (--count == 0)
5514b7815fSDavid Xu 			break;
5614b7815fSDavid Xu 	}
5714b7815fSDavid Xu 	if (!(cont_received && stop_received && exit_received))
5814b7815fSDavid Xu 		errx(1, "job signals lost");
5914b7815fSDavid Xu 
6014b7815fSDavid Xu 	printf("job control test OK.\n");
6114b7815fSDavid Xu }
6214b7815fSDavid Xu 
6314b7815fSDavid Xu void rtsig_handler(int sig, siginfo_t *si, void *ctx)
6414b7815fSDavid Xu {
6514b7815fSDavid Xu }
6614b7815fSDavid Xu 
6714b7815fSDavid Xu int main()
6814b7815fSDavid Xu {
6914b7815fSDavid Xu 	struct sigaction sa;
7014b7815fSDavid Xu 	sigset_t set;
7114b7815fSDavid Xu 	union sigval val;
7214b7815fSDavid Xu 
7314b7815fSDavid Xu 	/* test job control with empty signal queue */
7414b7815fSDavid Xu 	job_control_test();
7514b7815fSDavid Xu 
7614b7815fSDavid Xu 	/* now full fill signal queue in kernel */
7714b7815fSDavid Xu 	sigemptyset(&sa.sa_mask);
7814b7815fSDavid Xu 	sa.sa_flags = SA_SIGINFO;
7914b7815fSDavid Xu 	sa.sa_sigaction = rtsig_handler;
8014b7815fSDavid Xu 	sigaction(SIGRTMIN, &sa, NULL);
8114b7815fSDavid Xu 	sigemptyset(&set);
8214b7815fSDavid Xu 	sigaddset(&set, SIGRTMIN);
8314b7815fSDavid Xu 	sigprocmask(SIG_BLOCK, &set, NULL);
8414b7815fSDavid Xu 	val.sival_int = 1;
8514b7815fSDavid Xu 	while (sigqueue(getpid(), SIGRTMIN, val))
8614b7815fSDavid Xu 		;
8714b7815fSDavid Xu 
8814b7815fSDavid Xu 	/* signal queue is fully filled, test the job control again. */
8914b7815fSDavid Xu 	job_control_test();
9014b7815fSDavid Xu 	return (0);
9114b7815fSDavid Xu }
92