]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/compat/posix/v2_0/tests/mqueue1.c
Initial revision
[karo-tx-redboot.git] / packages / compat / posix / v2_0 / tests / mqueue1.c
1 /*========================================================================
2 //
3 //      mqueue1.c
4 //
5 //      POSIX Message queues tests
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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####
42 //
43 // Author(s):     jlarmour
44 // Contributors:  
45 // Date:          2000-05-18
46 // Purpose:       This file provides tests for POSIX mqueues
47 // Description:   
48 // Usage:         
49 //
50 //####DESCRIPTIONEND####
51 //
52 //======================================================================
53 */
54
55 /* CONFIGURATION */
56
57 #include <pkgconf/posix.h>
58
59 #ifndef CYGPKG_POSIX_MQUEUES
60 # define NA_MSG "Message queues not configured"
61 #endif
62
63 #ifdef NA_MSG
64 #include <cyg/infra/testcase.h>      // test API
65 void
66 cyg_user_start(void)
67 {
68     CYG_TEST_NA( NA_MSG );
69 }
70
71 #else
72
73 /* INCLUDES */
74
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
80
81 /* FUNCTIONS */
82
83 static int
84 my_memcmp(const void *m1, const void *m2, size_t n)
85 {
86     char *s1 = (char *)m1;
87     char *s2 = (char *)m2;
88
89     while (n--) {
90         if (*s1 != *s2)
91             return *s1 - *s2;
92         s1++;
93         s2++;
94     }
95     return 0;
96 } // my_memcmp()
97
98 //************************************************************************
99
100 int
101 main(void)
102 {
103     mqd_t q1, q2;
104     char buf[20];
105     ssize_t recvlen;
106     unsigned int prio;
107     struct mq_attr attr, oattr;
108     mode_t mode;
109     int err;
110
111     CYG_TEST_INIT();
112     CYG_TEST_INFO( "Starting POSIX message test 1" );
113
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" );
118
119     attr.mq_flags = 0;
120     attr.mq_maxmsg = 4;
121     attr.mq_msgsize = 20;
122     mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all
123
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)" );
126     
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" );
136                         
137     err = mq_send( q1, "Vik is brill", sizeof("Vik is brill"), 10 );
138
139     CYG_TEST_PASS_FAIL( 0 == err, "simple mq_send" );
140     
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" );
151                         
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" );
157     
158     q2 = mq_open( "/mq1", O_RDONLY );
159     CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "simple mq_open (read only)" );
160     
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" );
171
172     err = mq_close( q2 );
173     CYG_TEST_PASS_FAIL( 0 == err, "simple mq_close" );
174     
175     q2 = mq_open( "/mq1", O_RDONLY );
176     CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "mq_open reopen (read only)" );
177     
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" );
188
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" );
196
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" );
207
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" );
229
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" );
235     
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" );
240     
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)" );
245     
246     err = mq_send( q1, "", sizeof(""), 5 );
247     CYG_TEST_PASS_FAIL( 0 == err, "mq_send \"\"" );
248     
249     err = mq_send( q1, "I love Vik", sizeof("I love Vik"), 7 );
250     CYG_TEST_PASS_FAIL( 0 == err, "mq_send (different priority)" );
251     
252     err = mq_send( q1, "a lot!", sizeof("a lot!"), 7 );
253     CYG_TEST_PASS_FAIL( 0 == err, "mq_send (same priority)" );
254     
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)" );
257     
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" );
262     
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" );
273
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" );
282
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!",
287                                         sizeof("a lot!")),
288                         "received message data intact (prioritized) #2" );
289     CYG_TEST_PASS_FAIL( 7 == prio,
290                         "received at correct priority (prioritized) #2" );
291
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" );
300
301     recvlen = mq_receive( q2, buf, 0, &prio );
302     CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
303                         "mq_receive, zero-sized buffer" );
304
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, "",
309                                         sizeof("")),
310                         "received message data intact (prioritized) #4" );
311     CYG_TEST_PASS_FAIL( 5 == prio,
312                         "received at correct priority (prioritzed) #4" );
313
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" );
319     
320     err = mq_send( q1, "12345678901234567890", 20, 15 );
321     CYG_TEST_PASS_FAIL( 0 == err, "mq_send (before closing)" );
322     
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)" );
327
328     err = mq_unlink( "/mq1" );
329     CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink (before closing)" );
330
331     err = mq_close( q1 );
332     CYG_TEST_PASS_FAIL( 0 == err, "mq_close (send descriptor)" );
333
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)" );
341
342     err = mq_close( q2 );
343     CYG_TEST_PASS_FAIL( 0 == err, "mq_close (receive descriptor)" );
344
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" );
349
350     CYG_TEST_EXIT("POSIX message test 1");
351
352     return 0;
353 } // main()
354
355 //------------------------------------------------------------------------
356
357 #endif
358
359 /* EOF mqueue1.c */