]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/compat/posix/v2_0/tests/pmqueue2.c
Initial revision
[karo-tx-redboot.git] / packages / compat / posix / v2_0 / tests / pmqueue2.c
1 /*========================================================================
2 //
3 //      pmqueue2.c
4 //
5 //      POSIX Message queues tests - mq_notify
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 mqueue mq_notify
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 #elif !defined(CYGPKG_POSIX_SIGNALS)
62 # define NA_MSG "No POSIX signals configured"
63 #endif
64
65 #ifdef NA_MSG
66 #include <cyg/infra/testcase.h>      // test API
67 void
68 cyg_user_start(void)
69 {
70     CYG_TEST_INIT();
71     CYG_TEST_NA( NA_MSG );
72 }
73
74 #else
75
76 /* INCLUDES */
77
78 #include <fcntl.h>                   // O_*
79 #include <errno.h>                   // errno
80 #include <sys/stat.h>                // file modes
81 #include <mqueue.h>                  // Mqueue Header
82 #include <cyg/infra/testcase.h>      // test API
83 #include <signal.h>                  // signals
84
85 /* GLOBALS */
86 sig_atomic_t signals=0;
87 char buf[20];
88 unsigned int prio;
89
90
91 /* FUNCTIONS */
92
93 static int
94 my_memcmp(const void *m1, const void *m2, size_t n)
95 {
96     char *s1 = (char *)m1;
97     char *s2 = (char *)m2;
98
99     while (n--) {
100         if (*s1 != *s2)
101             return *s1 - *s2;
102         s1++;
103         s2++;
104     }
105     return 0;
106 } // my_memcmp()
107
108 static char *
109 my_strcpy(char *s1, const char *s2)
110 {
111     char *s = s1;
112     while (*s2) {
113         *s1++ = *s2++;
114     }
115     return s;
116 } // my_strcpy()
117
118 static size_t
119 my_strlen(const char *s)
120 {
121     const char *start = s;
122     while (*s)
123         s++;
124     return (s - start);
125 } // my_strcpy()
126
127
128
129 //************************************************************************
130
131 static void
132 sigusr1_handler( int signo, siginfo_t *info, void *context )
133 {
134     ssize_t recvlen;
135     char mybuf[20];
136     unsigned int myprio;
137     mqd_t *q = (mqd_t *)info->si_value.sival_ptr;
138
139     CYG_TEST_PASS_FAIL( SIGUSR1 == signo, "correct signal number #1" );
140     CYG_TEST_PASS_FAIL( SIGUSR1 == info->si_signo, "correct signal number #2" );
141     CYG_TEST_PASS_FAIL( SI_MESGQ == info->si_code, "correct signal code" );
142
143     signals++;
144
145     // retrieve message and compare with buf
146     recvlen = mq_receive( *q, mybuf, sizeof(mybuf), &myprio );
147     CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
148                         "receive message length" );
149     CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
150                         "received message data intact" );
151     CYG_TEST_PASS_FAIL( prio == myprio,
152                         "received at correct priority" );
153 }
154
155 //************************************************************************
156
157 int
158 main(void)
159 {
160     mqd_t q1;
161     struct mq_attr attr;
162     mode_t mode;
163     int err;
164     ssize_t recvlen;
165     char mybuf[20];
166     unsigned int myprio;
167     struct sigevent ev;
168     struct sigaction act;
169
170     CYG_TEST_INIT();
171     CYG_TEST_INFO( "Starting POSIX message test 2" );
172
173 #if 0
174     if ( 0 != pthread_create( &thr, NULL, &thread, NULL ) ) {
175         CYG_TEST_FAIL_FINISH( "Couldn't create a helper thread" );
176     }
177 #endif
178
179     attr.mq_flags = 0;
180     attr.mq_maxmsg = 4;
181     attr.mq_msgsize = 20;
182     mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all
183
184     q1 = mq_open( "/mq1", O_CREAT|O_NONBLOCK|O_RDWR, mode, &attr );
185     CYG_TEST_PASS_FAIL( q1 != (mqd_t)-1, "simple mq_open (write only)" );
186     
187     err = mq_getattr( q1, &attr );
188     CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr" );
189     CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
190                         (20 == attr.mq_msgsize) &&
191                         (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
192                         (O_RDWR == (attr.mq_flags & O_RDWR)) &&
193                         (0 == attr.mq_curmsgs ), "getattr attributes correct" );
194
195
196     act.sa_sigaction = &sigusr1_handler;
197     sigfillset( &act.sa_mask ); // enable all signals
198     act.sa_flags = SA_SIGINFO;
199     
200     if ( 0 != sigaction( SIGUSR1, &act, NULL ) ) {
201         CYG_TEST_FAIL_FINISH( "Couldn't register signal handler" );
202     }
203
204     ev.sigev_notify = SIGEV_SIGNAL;
205     ev.sigev_signo = SIGUSR1;
206     ev.sigev_value.sival_ptr = (void *)&q1;
207
208     err = mq_notify( q1, &ev );
209     CYG_TEST_PASS_FAIL( 0 == err, "simple mq_notify" );
210
211     my_strcpy( buf, "Vik is the best" );
212     prio = 7;
213     err = mq_send( q1, buf, my_strlen(buf), prio );
214
215     CYG_TEST_PASS_FAIL( 0 == err, "mq_send #1" );
216
217     CYG_TEST_PASS_FAIL( 1 == signals, "got notification" );
218
219     my_strcpy( buf, "Scrummy Vik" );
220     prio = 6;
221     err = mq_send( q1, buf, my_strlen(buf), prio );
222     CYG_TEST_PASS_FAIL( 0 == err, "mq_send #2" );
223
224     CYG_TEST_PASS_FAIL( 1 == signals, "correctly didn't get notification" );
225
226     recvlen = mq_receive( q1, mybuf, sizeof(mybuf), &myprio );
227     CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
228                         "receive message length" );
229     CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
230                         "received message data intact" );
231     CYG_TEST_PASS_FAIL( prio == myprio,
232                         "received at correct priority" );
233
234     err = mq_notify( q1, &ev );
235     CYG_TEST_PASS_FAIL( 0 == err, "mq_notify #2" );
236
237     err = mq_notify( q1, &ev );
238     CYG_TEST_PASS_FAIL( -1 == err, "second mq_notify returns error" );
239     CYG_TEST_PASS_FAIL( EBUSY == errno,
240                         "errno correct for second mq_notify error" );
241
242     err = mq_notify( q1, NULL );
243     CYG_TEST_PASS_FAIL( 0 == err, "clear notification" );
244
245     my_strcpy( buf, "Vik is k3wl" );
246     prio = 8;
247     err = mq_send( q1, buf, my_strlen(buf), prio );
248
249     CYG_TEST_PASS_FAIL( 0 == err, "mq_send #2" );
250
251     CYG_TEST_PASS_FAIL( 1 == signals, "correctly didn't get notification #2" );
252
253     recvlen = mq_receive( q1, mybuf, sizeof(mybuf), &myprio );
254     CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
255                         "receive message length" );
256     CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
257                         "received message data intact" );
258     CYG_TEST_PASS_FAIL( prio == myprio,
259                         "received at correct priority" );
260     
261     err = mq_close( q1 );
262     CYG_TEST_PASS_FAIL( 0 == err, "mq_close" );
263
264     err = mq_unlink( "/mq1" );
265     CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink" );
266
267     CYG_TEST_EXIT("POSIX message test 2");
268
269     return 0;
270 } // main()
271
272 //------------------------------------------------------------------------
273
274 #endif
275
276 /* EOF pmqueue2.c */