1 /*========================================================================
5 // POSIX Message queues tests
7 //========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //========================================================================
41 //#####DESCRIPTIONBEGIN####
43 // Author(s): jlarmour
46 // Purpose: This file provides tests for POSIX mqueues
50 //####DESCRIPTIONEND####
52 //======================================================================
57 #include <pkgconf/posix.h>
59 #ifndef CYGPKG_POSIX_MQUEUES
60 # define NA_MSG "Message queues not configured"
64 #include <cyg/infra/testcase.h> // test API
68 CYG_TEST_NA( NA_MSG );
75 #include <fcntl.h> // O_*
76 #include <errno.h> // errno
77 #include <sys/stat.h> // file modes
78 #include <mqueue.h> // Mqueue Header
79 #include <cyg/infra/testcase.h> // test API
84 my_memcmp(const void *m1, const void *m2, size_t n)
86 char *s1 = (char *)m1;
87 char *s2 = (char *)m2;
98 //************************************************************************
107 struct mq_attr attr, oattr;
112 CYG_TEST_INFO( "Starting POSIX message test 1" );
114 q1 = mq_open( "/mq1", O_RDWR );
115 CYG_TEST_PASS_FAIL( q1 == (mqd_t)-1, "error for non-existent queue" );
116 CYG_TEST_PASS_FAIL( ENOENT == errno,
117 "errno correct for non-existent queue" );
121 attr.mq_msgsize = 20;
122 mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all
124 q1 = mq_open( "/mq1", O_CREAT|O_NONBLOCK|O_WRONLY, mode, &attr );
125 CYG_TEST_PASS_FAIL( q1 != (mqd_t)-1, "simple mq_open (write only)" );
127 err = mq_getattr( q1, &attr );
128 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr" );
129 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
130 (20 == attr.mq_msgsize) &&
131 (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
132 (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
133 (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
134 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
135 (0 == attr.mq_curmsgs ), "getattr attributes correct" );
137 err = mq_send( q1, "Vik is brill", sizeof("Vik is brill"), 10 );
139 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_send" );
141 err = mq_getattr( q1, &attr );
142 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr after send" );
143 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
144 (20 == attr.mq_msgsize) &&
145 (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
146 (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
147 (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
148 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
149 (1 == attr.mq_curmsgs ),
150 "getattr attributes correct #2" );
152 q2 = mq_open( "/mq1", O_RDONLY|O_CREAT|O_EXCL );
153 CYG_TEST_PASS_FAIL( q2 == (mqd_t)-1,
154 "error for exclusive open of existing queue" );
155 CYG_TEST_PASS_FAIL( EEXIST == errno,
156 "errno correct for exclusive open of existing queue" );
158 q2 = mq_open( "/mq1", O_RDONLY );
159 CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "simple mq_open (read only)" );
161 err = mq_getattr( q2, &attr );
162 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr, different mqd_t" );
163 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
164 (20 == attr.mq_msgsize) &&
165 (O_NONBLOCK != (attr.mq_flags & O_NONBLOCK)) &&
166 (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
167 (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
168 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
169 (1 == attr.mq_curmsgs ),
170 "getattr attributes correct #3" );
172 err = mq_close( q2 );
173 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_close" );
175 q2 = mq_open( "/mq1", O_RDONLY );
176 CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "mq_open reopen (read only)" );
178 err = mq_getattr( q2, &attr );
179 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr, different mqd_t" );
180 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
181 (20 == attr.mq_msgsize) &&
182 (O_NONBLOCK != (attr.mq_flags & O_NONBLOCK)) &&
183 (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
184 (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
185 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
186 (1 == attr.mq_curmsgs ),
187 "getattr attributes correct #4" );
189 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
190 CYG_TEST_PASS_FAIL( recvlen == sizeof("Vik is brill"),
191 "receive message length" );
192 CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "Vik is brill",
193 sizeof("Vik is brill")),
194 "received message data intact" );
195 CYG_TEST_PASS_FAIL( 10 == prio, "received at correct priority" );
197 err = mq_getattr( q1, &attr );
198 CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr after send" );
199 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
200 (20 == attr.mq_msgsize) &&
201 (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
202 (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
203 (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
204 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
205 (0 == attr.mq_curmsgs ),
206 "getattr attributes correct #5" );
208 attr.mq_flags |= O_NONBLOCK;
209 err = mq_setattr( q2, &attr, &oattr );
210 CYG_TEST_PASS_FAIL( 0 == err, "mq_setattr O_NONBLOCK" );
211 CYG_TEST_PASS_FAIL( (4 == oattr.mq_maxmsg) &&
212 (20 == oattr.mq_msgsize) &&
213 (O_NONBLOCK != (oattr.mq_flags & O_NONBLOCK)) &&
214 (O_RDONLY == (oattr.mq_flags & O_RDONLY)) &&
215 (O_WRONLY != (oattr.mq_flags & O_WRONLY)) &&
216 (O_RDWR != (oattr.mq_flags & O_RDWR)) &&
217 (0 == oattr.mq_curmsgs ),
218 "old attribute correct" );
219 err = mq_getattr( q2, &attr );
220 CYG_TEST_PASS_FAIL( 0 == err, "mq_getattr after O_NONBLOCK" );
221 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
222 (20 == attr.mq_msgsize) &&
223 (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
224 (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
225 (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
226 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
227 (0 == attr.mq_curmsgs ),
228 "new attribute correct" );
230 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
231 CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
232 "mq_receive, empty buffer, non-blocking" );
233 CYG_TEST_PASS_FAIL( EAGAIN == errno,
234 "errno correct for non-blocking" );
236 err = mq_send( q2, "foo", sizeof("foo"), 1 );
237 CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send on read-only descriptor" );
238 CYG_TEST_PASS_FAIL( EBADF == errno,
239 "errno correct for mq_send on r/o descriptor" );
241 err = mq_send( q2, "supercalifragilisticexpealidocious", 21, 2 );
242 CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send (message too long)" );
243 CYG_TEST_PASS_FAIL( EMSGSIZE == errno,
244 "errno correct for mq_send (message too long)" );
246 err = mq_send( q1, "", sizeof(""), 5 );
247 CYG_TEST_PASS_FAIL( 0 == err, "mq_send \"\"" );
249 err = mq_send( q1, "I love Vik", sizeof("I love Vik"), 7 );
250 CYG_TEST_PASS_FAIL( 0 == err, "mq_send (different priority)" );
252 err = mq_send( q1, "a lot!", sizeof("a lot!"), 7 );
253 CYG_TEST_PASS_FAIL( 0 == err, "mq_send (same priority)" );
255 err = mq_send( q1, "Vik is a babe", sizeof("Vik is a babe"), 6 );
256 CYG_TEST_PASS_FAIL( 0 == err, "mq_send (middle priority)" );
258 err = mq_send( q1, "wibble", sizeof("wibble"), 6 );
259 CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send with full queue" );
260 CYG_TEST_PASS_FAIL( EAGAIN == errno,
261 "errno correct for mq_send full queue" );
263 err = mq_getattr( q2, &attr );
264 CYG_TEST_PASS_FAIL( 0 == err, "mq_getattr after sends" );
265 CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
266 (20 == attr.mq_msgsize) &&
267 (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
268 (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
269 (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
270 (O_RDWR != (attr.mq_flags & O_RDWR)) &&
271 (4 == attr.mq_curmsgs ),
272 "getattr attributes correct #5" );
274 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
275 CYG_TEST_PASS_FAIL( recvlen == sizeof("I love Vik"),
276 "receive message length (prioritized) #1" );
277 CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "I love Vik",
278 sizeof("I love Vik")),
279 "received message data intact (prioritized) #1" );
280 CYG_TEST_PASS_FAIL( 7 == prio,
281 "received at correct priority (prioritized) #1" );
283 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
284 CYG_TEST_PASS_FAIL( recvlen == sizeof("a lot!"),
285 "receive message length (prioritized) #2" );
286 CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "a lot!",
288 "received message data intact (prioritized) #2" );
289 CYG_TEST_PASS_FAIL( 7 == prio,
290 "received at correct priority (prioritized) #2" );
292 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
293 CYG_TEST_PASS_FAIL( recvlen == sizeof("Vik is a babe"),
294 "receive message length (prioritized) #3" );
295 CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "Vik is a babe",
296 sizeof("Vik is a babe")),
297 "received message data intact (prioritized) #3" );
298 CYG_TEST_PASS_FAIL( 6 == prio,
299 "received at correct priority (prioritized) #3" );
301 recvlen = mq_receive( q2, buf, 0, &prio );
302 CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
303 "mq_receive, zero-sized buffer" );
305 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
306 CYG_TEST_PASS_FAIL( recvlen == sizeof(""),
307 "receive message length (prioritized) #4" );
308 CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "",
310 "received message data intact (prioritized) #4" );
311 CYG_TEST_PASS_FAIL( 5 == prio,
312 "received at correct priority (prioritzed) #4" );
314 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
315 CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
316 "mq_receive, empty buffer, non-blocking #2" );
317 CYG_TEST_PASS_FAIL( EAGAIN == errno,
318 "errno correct for non-blocking #2" );
320 err = mq_send( q1, "12345678901234567890", 20, 15 );
321 CYG_TEST_PASS_FAIL( 0 == err, "mq_send (before closing)" );
323 err = mq_unlink( "/foo" );
324 CYG_TEST_PASS_FAIL( -1 == err, "mq_unlink (wrong name)" );
325 CYG_TEST_PASS_FAIL( ENOENT == errno,
326 "errno correct for mq_unlink (wrong name)" );
328 err = mq_unlink( "/mq1" );
329 CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink (before closing)" );
331 err = mq_close( q1 );
332 CYG_TEST_PASS_FAIL( 0 == err, "mq_close (send descriptor)" );
334 recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
335 CYG_TEST_PASS_FAIL( recvlen == 20,
336 "receive message length (mid close)" );
337 CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "12345678901234567890", 20 ),
338 "received message data intact (mid close)" );
339 CYG_TEST_PASS_FAIL( 15 == prio,
340 "received at correct priority (mid close)" );
342 err = mq_close( q2 );
343 CYG_TEST_PASS_FAIL( 0 == err, "mq_close (receive descriptor)" );
345 q1 = mq_open( "/mq1", O_RDONLY );
346 CYG_TEST_PASS_FAIL( q1 == (mqd_t)-1, "error for non-existent queue" );
347 CYG_TEST_PASS_FAIL( ENOENT == errno,
348 "errno correct for non-existent queue" );
350 CYG_TEST_EXIT("POSIX message test 1");
355 //------------------------------------------------------------------------