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