xref: /freebsd/contrib/netbsd-tests/kernel/t_mqueue.c (revision 8b25e8410533a6e69cceff910546b2dc485a5059)
1 /*	$NetBSD: t_mqueue.c,v 1.5 2017/01/10 22:10:22 christos Exp $ */
2 
3 /*
4  * Test for POSIX message queue priority handling.
5  *
6  * This file is in the Public Domain.
7  */
8 
9 #ifdef __FreeBSD__
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 
13 #include "freebsd_test_suite/macros.h"
14 #endif
15 
16 #include <atf-c.h>
17 #include <sys/stat.h>
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <unistd.h>
24 
25 #include <mqueue.h>
26 
27 #define	MQ_PRIO_BASE	24
28 
29 static void
30 send_msgs(mqd_t mqfd)
31 {
32 	char msg[2];
33 
34 	msg[1] = '\0';
35 
36 	msg[0] = 'a';
37 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
38 	    "mq_send 1 failed: %d", errno);
39 
40 	msg[0] = 'b';
41 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
42 	    "mq_send 2 failed: %d", errno);
43 
44 	msg[0] = 'c';
45 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1,
46 	    "mq_send 3 failed: %d", errno);
47 
48 	msg[0] = 'd';
49 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1,
50 	    "mq_send 4 failed: %d", errno);
51 
52 	msg[0] = 'e';
53 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1,
54 	    "mq_send 5 failed: %d", errno);
55 
56 	msg[0] = 'f';
57 	ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1,
58 	    "mq_send 6 failed: %d", errno);
59 }
60 
61 static void
62 receive_msgs(mqd_t mqfd)
63 {
64 	struct mq_attr mqa;
65 	char *m;
66 	unsigned p;
67 	int len;
68 
69 	ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d",
70 	    errno);
71 
72 	len = mqa.mq_msgsize;
73 	m = calloc(1, len);
74 	ATF_REQUIRE_MSG(m != NULL, "calloc failed");
75 
76 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
77 	    "mq_receive 1 failed: %d", errno);
78 	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b',
79 	    "mq_receive 1 prio/data mismatch");
80 
81 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
82 	    "mq_receive 2 failed: %d", errno);
83 	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f',
84 	    "mq_receive 2 prio/data mismatch");
85 
86 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
87 	    "mq_receive 3 failed: %d", errno);
88 	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a',
89 	    "mq_receive 3 prio/data mismatch");
90 
91 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
92 	    "mq_receive 4 failed: %d", errno);
93 	ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c',
94 	    "mq_receive 4 prio/data mismatch");
95 
96 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
97 	    "mq_receive 5 failed: %d", errno);
98 	ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd',
99 	    "mq_receive 5 prio/data mismatch");
100 
101 	ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1,
102 	    "mq_receive 6 failed: %d", errno);
103 	ATF_REQUIRE_MSG(p == 0 && m[0] == 'e',
104 	    "mq_receive 6 prio/data mismatch");
105 }
106 
107 ATF_TC(mqueue);
108 ATF_TC_HEAD(mqueue, tc)
109 {
110 
111 	atf_tc_set_md_var(tc, "timeout", "3");
112 	atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive");
113 }
114 
115 ATF_TC_BODY(mqueue, tc)
116 {
117 	int status;
118 	char *tmpdir;
119 	char template[32];
120 	char mq_name[64];
121 
122 #ifdef __FreeBSD__
123 	ATF_REQUIRE_KERNEL_MODULE("mqueuefs");
124 #endif
125 
126 	strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template));
127 	tmpdir = mkdtemp(template);
128 	ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno);
129 #ifdef __FreeBSD__
130 	snprintf(mq_name, sizeof(mq_name), "/t_mqueue");
131 #else
132 	snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir);
133 #endif
134 
135 	mqd_t mqfd;
136 
137 	mqfd = mq_open(mq_name, O_RDWR | O_CREAT,
138 	    S_IRUSR | S_IRWXG | S_IROTH, NULL);
139 #ifdef __FreeBSD__
140 	ATF_REQUIRE_MSG(mqfd != (mqd_t)-1, "mq_open failed: %d", errno);
141 #else
142 	ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno);
143 #endif
144 
145 	send_msgs(mqfd);
146 	receive_msgs(mqfd);
147 
148 	status = mq_close(mqfd);
149 	ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno);
150 }
151 
152 ATF_TP_ADD_TCS(tp)
153 {
154 	ATF_TP_ADD_TC(tp, mqueue);
155 
156 	return atf_no_error();
157 }
158