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