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