1
2 #include <sys/types.h>
3 #include <sys/select.h>
4 #include <sys/wait.h>
5 #include <err.h>
6 #include <fcntl.h>
7 #include <mqueue.h>
8 #include <signal.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12
13 #define MQNAME "/mytstqueue3"
14 #define LOOPS 1000
15 #define PRIO 10
16
17 static void
sighandler(int sig __unused)18 sighandler(int sig __unused)
19 {
20 write(1, "timeout\n", 8);
21 _exit(1);
22 }
23
24 int
main(void)25 main(void)
26 {
27 fd_set set;
28 struct mq_attr attr;
29 int status;
30 mqd_t mq;
31 pid_t pid;
32
33 mq_unlink(MQNAME);
34
35 attr.mq_maxmsg = 5;
36 attr.mq_msgsize = 128;
37 mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
38 if (mq == (mqd_t)-1)
39 err(1, "mq_open()");
40 status = mq_getattr(mq, &attr);
41 if (status)
42 err(1, "mq_getattr()");
43
44 pid = fork();
45 if (pid == 0) { /* child */
46 char *buf;
47 int j, i;
48 unsigned int prio;
49
50 mq_close(mq);
51
52 signal(SIGALRM, sighandler);
53
54 mq = mq_open(MQNAME, O_RDWR);
55 if (mq == (mqd_t)-1)
56 err(1, "child process: mq_open");
57 buf = malloc(attr.mq_msgsize);
58 for (j = 0; j < LOOPS; ++j) {
59 FD_ZERO(&set);
60 FD_SET(mq_getfd_np(mq), &set);
61 alarm(3);
62 status = select(mq_getfd_np(mq) + 1, &set, NULL,
63 NULL, NULL);
64 if (status != 1)
65 err(1, "child process: select()");
66 status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
67 if (status == -1)
68 err(2, "child process: mq_receive");
69 for (i = 0; i < attr.mq_msgsize; ++i)
70 if (buf[i] != i)
71 err(3, "message data corrupted");
72 if (prio != PRIO)
73 err(4, "priority is incorrect: %d", prio);
74 }
75 alarm(0);
76 free(buf);
77 mq_close(mq);
78 return (0);
79 } else if (pid == -1) {
80 err(1, "fork()");
81 } else {
82 char *buf;
83 int i, j;
84
85 signal(SIGALRM, sighandler);
86 buf = malloc(attr.mq_msgsize);
87 for (j = 0; j < LOOPS; ++j) {
88 for (i = 0; i < attr.mq_msgsize; ++i) {
89 buf[i] = i;
90 }
91 alarm(3);
92 FD_ZERO(&set);
93 FD_SET(mq_getfd_np(mq), &set);
94 status = select(mq_getfd_np(mq) + 1, NULL, &set,
95 NULL, NULL);
96 if (status != 1)
97 err(1, "select()");
98 status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
99 if (status) {
100 kill(pid, SIGKILL);
101 err(2, "mq_send()");
102 }
103 }
104 alarm(3);
105 wait(&status);
106 alarm(0);
107 }
108 status = mq_close(mq);
109 if (status)
110 err(1, "mq_close");
111 mq_unlink(MQNAME);
112 return (0);
113 }
114