xref: /freebsd/tests/sys/mqueue/mqtest5.c (revision e100f6a2fc03d6f8c268f237f595533ea8044810)
1*e100f6a2SEnji Cooper /* $FreeBSD$ */
2*e100f6a2SEnji Cooper 
3*e100f6a2SEnji Cooper #include <sys/types.h>
4*e100f6a2SEnji Cooper #include <sys/event.h>
5*e100f6a2SEnji Cooper #include <sys/select.h>
6*e100f6a2SEnji Cooper #include <sys/wait.h>
7*e100f6a2SEnji Cooper #include <err.h>
8*e100f6a2SEnji Cooper #include <fcntl.h>
9*e100f6a2SEnji Cooper #include <mqueue.h>
10*e100f6a2SEnji Cooper #include <signal.h>
11*e100f6a2SEnji Cooper #include <stdio.h>
12*e100f6a2SEnji Cooper #include <stdlib.h>
13*e100f6a2SEnji Cooper #include <unistd.h>
14*e100f6a2SEnji Cooper 
15*e100f6a2SEnji Cooper #define MQNAME	"/mytstqueue5"
16*e100f6a2SEnji Cooper #define LOOPS	1000
17*e100f6a2SEnji Cooper #define PRIO	10
18*e100f6a2SEnji Cooper 
19*e100f6a2SEnji Cooper static void
20*e100f6a2SEnji Cooper sighandler(int sig __unused)
21*e100f6a2SEnji Cooper {
22*e100f6a2SEnji Cooper 	write(1, "timeout\n", 8);
23*e100f6a2SEnji Cooper 	_exit(1);
24*e100f6a2SEnji Cooper }
25*e100f6a2SEnji Cooper 
26*e100f6a2SEnji Cooper int
27*e100f6a2SEnji Cooper main(void)
28*e100f6a2SEnji Cooper {
29*e100f6a2SEnji Cooper 	int status;
30*e100f6a2SEnji Cooper 	struct mq_attr attr;
31*e100f6a2SEnji Cooper 	struct sigaction sa;
32*e100f6a2SEnji Cooper 	sigset_t set;
33*e100f6a2SEnji Cooper 	siginfo_t info;
34*e100f6a2SEnji Cooper 	mqd_t mq;
35*e100f6a2SEnji Cooper 	pid_t pid;
36*e100f6a2SEnji Cooper 
37*e100f6a2SEnji Cooper 	mq_unlink(MQNAME);
38*e100f6a2SEnji Cooper 
39*e100f6a2SEnji Cooper 	sigemptyset(&set);
40*e100f6a2SEnji Cooper 	sigaddset(&set, SIGRTMIN);
41*e100f6a2SEnji Cooper 	sigprocmask(SIG_BLOCK, &set, NULL);
42*e100f6a2SEnji Cooper 	sigemptyset(&sa.sa_mask);
43*e100f6a2SEnji Cooper 	sa.sa_flags = SA_SIGINFO;
44*e100f6a2SEnji Cooper 	sa.sa_sigaction = (void *) SIG_DFL;
45*e100f6a2SEnji Cooper 	sigaction(SIGRTMIN, &sa, NULL);
46*e100f6a2SEnji Cooper 
47*e100f6a2SEnji Cooper 	attr.mq_maxmsg  = 5;
48*e100f6a2SEnji Cooper 	attr.mq_msgsize = 128;
49*e100f6a2SEnji Cooper 	mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
50*e100f6a2SEnji Cooper 	if (mq == (mqd_t)-1)
51*e100f6a2SEnji Cooper 		err(1, "mq_open()");
52*e100f6a2SEnji Cooper 	status = mq_getattr(mq, &attr);
53*e100f6a2SEnji Cooper 	if (status)
54*e100f6a2SEnji Cooper 		err(1, "mq_getattr()");
55*e100f6a2SEnji Cooper 	pid = fork();
56*e100f6a2SEnji Cooper 	if (pid == 0) { /* child */
57*e100f6a2SEnji Cooper 		int prio, j, i;
58*e100f6a2SEnji Cooper 		char *buf;
59*e100f6a2SEnji Cooper 		struct sigevent sigev;
60*e100f6a2SEnji Cooper 
61*e100f6a2SEnji Cooper 		signal(SIGALRM, sighandler);
62*e100f6a2SEnji Cooper 
63*e100f6a2SEnji Cooper 		sigev.sigev_notify = SIGEV_SIGNAL;
64*e100f6a2SEnji Cooper 		sigev.sigev_signo = SIGRTMIN;
65*e100f6a2SEnji Cooper 		sigev.sigev_value.sival_int = 2;
66*e100f6a2SEnji Cooper 
67*e100f6a2SEnji Cooper 		mq_close(mq);
68*e100f6a2SEnji Cooper 		mq = mq_open(MQNAME, O_RDWR | O_NONBLOCK);
69*e100f6a2SEnji Cooper 		if (mq == (mqd_t)-1)
70*e100f6a2SEnji Cooper 			err(1, "child: mq_open");
71*e100f6a2SEnji Cooper 		buf = malloc(attr.mq_msgsize);
72*e100f6a2SEnji Cooper 		for (j = 0; j < LOOPS; ++j) {
73*e100f6a2SEnji Cooper 			alarm(3);
74*e100f6a2SEnji Cooper 			status = mq_notify(mq, &sigev);
75*e100f6a2SEnji Cooper 			if (status)
76*e100f6a2SEnji Cooper 				err(1, "child: mq_notify");
77*e100f6a2SEnji Cooper 			status = sigwaitinfo(&set, &info);
78*e100f6a2SEnji Cooper 			if (status == -1)
79*e100f6a2SEnji Cooper 				err(1, "child: sigwaitinfo");
80*e100f6a2SEnji Cooper 			if (info.si_value.sival_int != 2)
81*e100f6a2SEnji Cooper 				err(1, "child: sival_int");
82*e100f6a2SEnji Cooper 			status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
83*e100f6a2SEnji Cooper 			if (status == -1)
84*e100f6a2SEnji Cooper 				err(2, "child: mq_receive");
85*e100f6a2SEnji Cooper 			for (i = 0; i < attr.mq_msgsize; ++i)
86*e100f6a2SEnji Cooper 				if (buf[i] != i)
87*e100f6a2SEnji Cooper 					err(3, "child: message data corrupted");
88*e100f6a2SEnji Cooper 			if (prio != PRIO)
89*e100f6a2SEnji Cooper 				err(4, "child: priority is incorrect: %d",
90*e100f6a2SEnji Cooper 					 prio);
91*e100f6a2SEnji Cooper 		}
92*e100f6a2SEnji Cooper 		alarm(0);
93*e100f6a2SEnji Cooper 		free(buf);
94*e100f6a2SEnji Cooper 		mq_close(mq);
95*e100f6a2SEnji Cooper 		return (0);
96*e100f6a2SEnji Cooper 	} else if (pid == -1) {
97*e100f6a2SEnji Cooper 		err(1, "fork()");
98*e100f6a2SEnji Cooper 	} else {
99*e100f6a2SEnji Cooper 		char *buf;
100*e100f6a2SEnji Cooper 		int i, j;
101*e100f6a2SEnji Cooper 
102*e100f6a2SEnji Cooper 		signal(SIGALRM, sighandler);
103*e100f6a2SEnji Cooper 		buf = malloc(attr.mq_msgsize);
104*e100f6a2SEnji Cooper 		for (j = 0; j < LOOPS; ++j) {
105*e100f6a2SEnji Cooper 			for (i = 0; i < attr.mq_msgsize; ++i) {
106*e100f6a2SEnji Cooper 				buf[i] = i;
107*e100f6a2SEnji Cooper 			}
108*e100f6a2SEnji Cooper 			alarm(3);
109*e100f6a2SEnji Cooper 			status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
110*e100f6a2SEnji Cooper 			if (status) {
111*e100f6a2SEnji Cooper 				kill(pid, SIGKILL);
112*e100f6a2SEnji Cooper 				err(2, "mq_send()");
113*e100f6a2SEnji Cooper 			}
114*e100f6a2SEnji Cooper 		}
115*e100f6a2SEnji Cooper 		alarm(3);
116*e100f6a2SEnji Cooper 		wait(&status);
117*e100f6a2SEnji Cooper 		alarm(0);
118*e100f6a2SEnji Cooper 	}
119*e100f6a2SEnji Cooper 	status = mq_close(mq);
120*e100f6a2SEnji Cooper 	if (status)
121*e100f6a2SEnji Cooper 		err(1, "mq_close");
122*e100f6a2SEnji Cooper 	mq_unlink(MQNAME);
123*e100f6a2SEnji Cooper 	return (0);
124*e100f6a2SEnji Cooper }
125