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