1fe033788SKonstantin Belousov
2fe033788SKonstantin Belousov #include <sys/types.h>
3fe033788SKonstantin Belousov #include <sys/wait.h>
4fe033788SKonstantin Belousov #include <err.h>
598fd65daSDavid Xu #include <fcntl.h>
6fe033788SKonstantin Belousov #include <mqueue.h>
798fd65daSDavid Xu #include <signal.h>
8fe033788SKonstantin Belousov #include <stdio.h>
9fe033788SKonstantin Belousov #include <stdlib.h>
1098fd65daSDavid Xu #include <unistd.h>
1198fd65daSDavid Xu
1298fd65daSDavid Xu #define MQNAME "/mytstqueue2"
1398fd65daSDavid Xu #define LOOPS 1000
1498fd65daSDavid Xu #define PRIO 10
1598fd65daSDavid Xu
16*e100f6a2SEnji Cooper static void
alarmhandler(int sig __unused)17*e100f6a2SEnji Cooper alarmhandler(int sig __unused)
1898fd65daSDavid Xu {
1998fd65daSDavid Xu write(1, "timeout\n", 8);
2098fd65daSDavid Xu _exit(1);
2198fd65daSDavid Xu }
2298fd65daSDavid Xu
23*e100f6a2SEnji Cooper int
main(void)24*e100f6a2SEnji Cooper main(void)
2598fd65daSDavid Xu {
2698fd65daSDavid Xu struct mq_attr attr;
271d6328e1SDavid Xu mqd_t mq;
28*e100f6a2SEnji Cooper int status;
29*e100f6a2SEnji Cooper pid_t pid;
3098fd65daSDavid Xu
3198fd65daSDavid Xu mq_unlink(MQNAME);
3298fd65daSDavid Xu
3398fd65daSDavid Xu attr.mq_maxmsg = 5;
3498fd65daSDavid Xu attr.mq_msgsize = 128;
3598fd65daSDavid Xu mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
361d6328e1SDavid Xu if (mq == (mqd_t)-1)
3798fd65daSDavid Xu err(1, "mq_open");
3898fd65daSDavid Xu status = mq_getattr(mq, &attr);
3998fd65daSDavid Xu if (status)
4098fd65daSDavid Xu err(1, "mq_getattr");
4198fd65daSDavid Xu pid = fork();
4298fd65daSDavid Xu if (pid == 0) { /* child */
4398fd65daSDavid Xu char *buf;
44*e100f6a2SEnji Cooper int j, i;
45*e100f6a2SEnji Cooper unsigned int prio;
4698fd65daSDavid Xu
4798fd65daSDavid Xu mq_close(mq);
4898fd65daSDavid Xu
4998fd65daSDavid Xu signal(SIGALRM, alarmhandler);
5098fd65daSDavid Xu
5198fd65daSDavid Xu mq = mq_open(MQNAME, O_RDWR);
521d6328e1SDavid Xu if (mq == (mqd_t)-1)
5398fd65daSDavid Xu err(1, "child: mq_open");
5498fd65daSDavid Xu buf = malloc(attr.mq_msgsize);
5598fd65daSDavid Xu for (j = 0; j < LOOPS; ++j) {
5698fd65daSDavid Xu alarm(3);
5798fd65daSDavid Xu status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
5898fd65daSDavid Xu if (status == -1)
5998fd65daSDavid Xu err(2, "child: mq_receive");
6098fd65daSDavid Xu for (i = 0; i < attr.mq_msgsize; ++i)
6198fd65daSDavid Xu if (buf[i] != i)
6298fd65daSDavid Xu err(3, "child: message data corrupted");
6398fd65daSDavid Xu if (prio != PRIO)
6498fd65daSDavid Xu err(4, "child: priority is incorrect: %d",
6598fd65daSDavid Xu prio);
6698fd65daSDavid Xu }
6798fd65daSDavid Xu alarm(0);
6898fd65daSDavid Xu free(buf);
6998fd65daSDavid Xu mq_close(mq);
7098fd65daSDavid Xu return (0);
7198fd65daSDavid Xu } else if (pid == -1) {
7298fd65daSDavid Xu err(1, "fork()");
7398fd65daSDavid Xu } else {
7498fd65daSDavid Xu char *buf;
75*e100f6a2SEnji Cooper int i, j;
7698fd65daSDavid Xu
7798fd65daSDavid Xu signal(SIGALRM, alarmhandler);
7898fd65daSDavid Xu buf = malloc(attr.mq_msgsize);
7998fd65daSDavid Xu for (j = 0; j < LOOPS; ++j) {
8098fd65daSDavid Xu for (i = 0; i < attr.mq_msgsize; ++i)
8198fd65daSDavid Xu buf[i] = i;
8298fd65daSDavid Xu alarm(3);
8398fd65daSDavid Xu status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
8498fd65daSDavid Xu if (status)
8598fd65daSDavid Xu err(1, "mq_send");
8698fd65daSDavid Xu }
8798fd65daSDavid Xu alarm(3);
8898fd65daSDavid Xu wait(&status);
8998fd65daSDavid Xu alarm(0);
9098fd65daSDavid Xu }
9198fd65daSDavid Xu status = mq_close(mq);
9298fd65daSDavid Xu if (status)
9398fd65daSDavid Xu err(1, "mq_close");
9498fd65daSDavid Xu mq_unlink(MQNAME);
9598fd65daSDavid Xu return (0);
9698fd65daSDavid Xu }
97