source: rtems/testsuites/psxtests/psxmsgq01/init.c @ 1b4f2b30

4.104.114.84.95
Last change on this file since 1b4f2b30 was 1b4f2b30, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 16, 2004 at 9:24:30 AM

Remove stray white spaces.

  • Property mode set to 100644
File size: 34.3 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-1999.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 *  $Id$
10 */
11
12#define CONFIGURE_INIT
13#include "system.h"
14#include <sched.h>
15#include <fcntl.h>
16#include <time.h>
17#include <tmacros.h>
18#include <signal.h>   /* signal facilities */
19
20typedef struct {
21  char         msg[ 50 ];
22  int          size;
23  unsigned int priority;
24}Test_Message_t;
25Test_Message_t Predefined_Msgs[MAXMSG+1];
26Test_Message_t Predefined_Msgs[MAXMSG+1] = {
27  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
28  { "",           1, 1             },  /* NULL  Message      low  */
29  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */
30  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
31  { "1",          2, 0             },  /* Cause Overflow Behavior */
32};
33int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
34
35
36typedef struct {
37  mqd_t              mq;
38  Test_Queue_Types   index;
39  char              *name;
40  int                oflag;
41  int                maxmsg;
42  int                msgsize;
43  int                count;
44} Test_queue_type;
45
46Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES ] =
47{
48  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
49  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
50  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
51  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
52  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
53  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
54};
55
56#define RW_NAME             Test_q[ RW_QUEUE ].name
57#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
58#define RD_NAME             Test_q[ RD_QUEUE ].name
59#define WR_NAME             Test_q[ WR_QUEUE ].name
60#define BLOCKING_NAME       Test_q[ BLOCKING ].name
61#define CLOSED_NAME         Test_q[ CLOSED ].name
62
63#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
64#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
65#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
66#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
67#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
68#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
69
70/*
71 * Outputs a header at each test section.
72 */
73void Start_Test(
74  char *description
75)
76{
77  printf( "_______________%s\n", description );
78}
79
80
81void Validate_attributes(
82    mqd_t  mq,
83    int    oflag,
84    int    msg_count
85)
86{
87  int             status;
88  struct mq_attr  attr;
89
90  status = mq_getattr( mq, &attr );
91  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
92
93  if ( mq != Test_q[ DEFAULT_RW ].mq ){
94    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
95    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
96  }
97
98  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
99  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
100}
101
102char Queue_Name[PATH_MAX + 2];
103#define Get_Queue_Name( i )  Test_q[i].name
104
105char *Build_Queue_Name( int i ) {
106  sprintf(Queue_Name,"mq%d", i+1 );
107  return Queue_Name;
108}
109
110char *Get_Too_Long_Name()
111{
112  int i;
113
114  for ( i=0; i< PATH_MAX+1; i++ )
115    Queue_Name[i] = 'N';
116  Queue_Name[i] = '\0';
117  return Queue_Name;
118}
119
120
121void open_test_queues()
122{
123  struct mq_attr   attr;
124  int              status;
125  Test_queue_type *tq;
126  int              que;
127
128  attr.mq_maxmsg  = MAXMSG;
129  attr.mq_msgsize = MSGSIZE;
130
131  puts( "Init: Open Test Queues" );
132
133  for( que = 0; que < NUMBER_OF_TEST_QUEUES; que++ ) {
134
135    tq = &Test_q[ que ];
136    if ( que == DEFAULT_RW)
137      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
138    else
139      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
140
141    assert( Test_q[que].mq != (-1) );
142  }
143
144  status = mq_close( Test_q[CLOSED].mq );
145  fatal_posix_service_status( status, 0, "mq_close message queue");
146  status = mq_unlink( CLOSED_NAME );
147  fatal_posix_service_status( status, 0, "mq_unlink message queue");
148}
149
150/*
151 * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues
152 * opened but closes the rest.
153 */
154
155void validate_mq_open_error_codes()
156{
157  int             i;
158  mqd_t           n_mq2;
159  struct mq_attr  attr;
160  int             status;
161  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1];
162
163  attr.mq_maxmsg  = MAXMSG;
164  attr.mq_msgsize = MSGSIZE;
165
166  Start_Test( "mq_open errors" );
167
168  /*
169   * XXX EINVAL - inappropriate name was given for the message queue
170   */
171
172  /*
173   * EINVAL - Create with negative maxmsg.
174   */
175
176  attr.mq_maxmsg = -1;
177  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
178  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
179  fatal_posix_service_status(
180    (int) n_mq2, (int ) (-1), "mq_open error return status" );
181  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
182  attr.mq_maxmsg  = MAXMSG;
183
184  /*
185   * EINVAL - Create withnegative msgsize.
186   */
187
188  attr.mq_msgsize = -1;
189  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
190  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
191  fatal_posix_service_status(
192    (int) n_mq2, (int ) (-1), "mq_open error return status" );
193  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
194  attr.mq_msgsize = MSGSIZE;
195
196  /*
197   * ENOENT - Open a non-created file.
198   */
199
200  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
201  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
202  fatal_posix_service_status(
203    (int) n_mq2, (int ) (-1), "mq_open error return status" );
204  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
205
206  /*
207   * XXX EINTR  - call was interrupted by a signal
208   */
209
210  /*
211   * ENAMETOOLONG - Give a name greater than PATH_MAX.
212   */
213
214  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
215  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
216  fatal_posix_service_status(
217    (int) n_mq2, (int ) (-1), "mq_open error return status" );
218  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
219
220  /*
221   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
222   *       Per implementation not possible.
223   */
224
225  /*
226   * EEXIST - Create an existing queue.
227   */
228
229  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
230  open_mq[0] = mq_open(
231    Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
232  assert( open_mq[0] != (-1) );
233
234  n_mq2 = mq_open(
235    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
236  fatal_posix_service_status(
237    (int) n_mq2, (int ) (-1), "mq_open error return status" );
238  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
239
240  status = mq_unlink( Build_Queue_Name(0) );
241  fatal_posix_service_status( status, 0, "mq_unlink message queue");
242
243  status = mq_close( open_mq[0]);
244  fatal_posix_service_status( status, 0, "mq_close message queue");
245
246  /*
247   * Open maximum number of message queues
248   */
249
250  puts( "Init: mq_open - SUCCESSFUL" );
251  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
252    open_mq[i] = mq_open(
253      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
254    assert( open_mq[i] != (-1) );
255    assert( open_mq[i] );
256    /*XXX - Isn't there a more general check */
257/* JRS     printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
258  }
259
260  /*
261   * XXX EACCES - permission to create is denied.
262   */
263
264  /*
265   * XXX EACCES - queue exists permissions specified by o_flag are denied.
266   */
267
268  /*
269   * XXX EMFILE  - Too many message queues in use by the process
270   */
271
272  /*
273   * ENFILE -  Too many message queues open in the system
274   */
275
276  puts( "Init: mq_open - system is out of resources (ENFILE)" );
277  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
278  fatal_posix_service_status(
279    (int) n_mq2, (int ) (-1), "mq_open error return status" );
280  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
281
282  /*
283   * Unlink and Close all queues.
284   */
285
286  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
287  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
288
289    status = mq_close( open_mq[i]);
290    fatal_posix_service_status( status, 0, "mq_close message queue");
291
292    status = mq_unlink( Build_Queue_Name(i) );
293    if ( status == -1 )
294      perror( "mq_unlink" );
295    fatal_posix_service_status( status, 0, "mq_unlink message queue");
296    /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
297  }
298}
299
300void validate_mq_unlink_error_codes()
301{
302  int             status;
303
304  Start_Test( "mq_unlink errors" );
305
306  /*
307   * XXX - EACCES Permission Denied
308   */
309
310  /*
311   * ENAMETOOLONG - Give a name greater than PATH_MAX.
312   */
313
314  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
315  status = mq_unlink( Get_Too_Long_Name() );
316  fatal_posix_service_status( status, -1, "mq_unlink error return status");
317  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
318
319  /*
320   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
321   *       Per implementation not possible.
322   */
323
324  /*
325   *  ENOENT - Unlink an unopened queue
326   */
327
328  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
329  status = mq_unlink( CLOSED_NAME );
330  fatal_posix_service_status( status, -1, "mq_unlink error return status");
331  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
332
333  /*
334   * XXX - The following were not listed in the POSIX document as
335   *       possible errors.  Under other commands the EINVAL is
336   *       given for these conditions.
337   */
338
339  /*
340   *  EINVAL - Unlink a queue with no name
341   */
342
343  puts( "Init: mq_unlink (NULL) - EINVAL" );
344  status = mq_unlink( NULL );
345  fatal_posix_service_status( status, -1, "mq_unlink error return status");
346  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
347
348  /*
349   *  EINVAL - Unlink a queue with a null name
350   */
351
352  puts( "Init: mq_unlink (\"\") - EINVAL" );
353  status = mq_unlink( "" );
354  fatal_posix_service_status( status, -1, "mq_unlink error return status");
355  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
356}
357
358void validate_mq_close_error_codes()
359{
360  int             status;
361
362  Start_Test( "mq_close errors" );
363
364  /*
365   * EBADF - Close a queue that is not open.
366   */
367
368  puts( "Init: mq_close - unopened queue (EBADF)" );
369  status = mq_close( Test_q[CLOSED].mq );
370  fatal_posix_service_status( status, -1, "mq_close error return status");
371  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
372}
373
374
375void validate_mq_getattr_error_codes()
376{
377  struct mq_attr  attr;
378  int             status;
379
380  Start_Test( "mq_getattr errors" );
381
382  /*
383   * EBADF - Get the attributes from a closed queue.
384   */
385
386  puts( "Init: mq_getattr - unopened queue (EBADF)" );
387  status = mq_getattr( Test_q[CLOSED].mq, &attr );
388  fatal_posix_service_status( status, -1, "mq_close error return status");
389  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
390
391  /*
392   * XXX - The following are not listed in the POSIX manual but
393   *       may occur.
394   */
395
396  /*
397   * EINVAL - NULL attributes
398   */
399
400  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
401  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
402  fatal_posix_service_status( status, -1, "mq_close error return status");
403  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL");
404
405}
406
407
408void Send_msg_to_que(
409  int que,
410  int msg
411)
412{
413  Test_Message_t *ptr = &Predefined_Msgs[msg];
414  int             status;
415
416  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
417  fatal_posix_service_status( status, 0, "mq_send valid return status");
418  Test_q[que].count++;
419}
420
421void Show_send_msg_to_que(
422  char *task_name,
423  int   que,
424  int   msg
425)
426{
427  Test_Message_t *ptr = &Predefined_Msgs[msg];
428  printf( "%s mq_send -  to %s msg: %s priority %d\n",
429    task_name, Test_q[que].name, ptr->msg, ptr->priority);
430  Send_msg_to_que( que, msg );
431}
432
433void verify_queues_full(
434  char *task_name
435)
436{
437  int          que;
438
439  /*
440   * Validate that the queues are full.
441   */
442
443  printf( "%s Verify Queues are full\n", task_name );
444  for( que = RW_QUEUE; que < CLOSED; que++ )
445    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
446
447}
448void verify_queues_empty(
449  char *task_name
450)
451{
452  int             que;
453
454  printf( "%s Verify Queues are empty\n", task_name );
455  for( que = RW_QUEUE; que < CLOSED; que++ )
456    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
457}
458
459int fill_message_queues(
460  char *task_name
461)
462{
463  int             msg;
464  int             que;
465
466
467  verify_queues_empty( task_name );
468
469  /*
470   * Fill Queue with predefined messages.
471   */
472
473  printf( "%s Fill Queues with messages\n", task_name );
474  for(msg=0; msg<MAXMSG; msg++){
475    for( que = RW_QUEUE; que < CLOSED; que++ ) {
476      Send_msg_to_que( que, msg );
477    }
478  }
479
480  verify_queues_full( "Init:" );
481  return msg;
482}
483
484
485void Read_msg_from_que(
486  int que,
487  int msg
488)
489{
490  unsigned int    priority;
491  Test_Message_t *ptr;
492  int             status;
493  char            message[100];
494  char            err_msg[100];
495
496  ptr = &Predefined_Msgs[msg];
497  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
498  Test_q[que].count--;
499
500  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
501  fatal_int_service_status( status, ptr->size, err_msg );
502
503  assert( !strcmp( message, ptr->msg ) );
504  strcpy( message, "No Message" );
505
506  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
507  fatal_int_service_status(priority, ptr->priority, err_msg );
508}
509
510int empty_message_queues(
511  char *task_name
512)
513{
514  int que;
515  int i;
516
517  printf( "%s Empty all Queues\n", task_name );
518  for( que = RW_QUEUE; que < CLOSED; que++ ) {
519    for(i=0; Test_q[que].count != 0; i++ )
520      Read_msg_from_que( que,  Priority_Order[i] );
521
522    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
523  }
524  return 0;
525}
526
527/*
528 * Returns the number of messages queued after the test on the
529 * first queue.
530 */
531
532int validate_mq_send_error_codes( )
533{
534  int             status;
535  int             i;
536  char           *str;
537
538  Start_Test( "mq_send errors" );
539
540  /*
541   * EBADF - Write to a closed queue.
542   */
543
544  puts( "Init: mq_send - Closed message queue (EBADF)" );
545  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
546  fatal_posix_service_status( status, -1, "mq_send error return status");
547  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
548
549  /*
550   * EBADF - Write to a read only  queue.
551   */
552
553  puts( "Init: mq_send - Read only message queue (EBADF)" );
554  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
555  fatal_posix_service_status( status, -1, "mq_send error return status");
556  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
557
558  /*
559   * XXX - EINTR      Signal interrupted the call.
560   *
561  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
562  status = mq_send( Test_q, "", 0xffff, 0 );
563  fatal_posix_service_status( status, -1, "mq_send error return status");
564  fatal_posix_service_status( errno, E, "mq_send errno E");
565   */
566
567  /*
568   * EINVAL priority is out of range.
569   */
570
571  puts( "Init: mq_send - Priority out of range (EINVAL)" );
572  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
573  fatal_posix_service_status( status, -1, "mq_send error return status");
574  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
575
576  /*
577   *  EMSGSIZE - Message size larger than msg_len
578   *             Validates that msgsize is stored correctly.
579   */
580
581  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
582  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
583  fatal_posix_service_status( status, -1, "mq_send error return status");
584  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
585
586  i = fill_message_queues( "Init:" );
587
588  /*
589   * ENOSYS - send not supported
590  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
591  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
592  fatal_posix_service_status( status, -1, "mq_send error return status");
593  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
594
595  status = mq_close( n_mq1 );
596  fatal_posix_service_status( status, 0, "mq_close message queue");
597
598  status = mq_unlink( "read_only" );
599  fatal_posix_service_status( status, 0, "mq_unlink message queue");
600   */
601
602  /*
603   * EAGAIN - O_NONBLOCK and message queue is full.
604   */
605
606  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
607  str = Predefined_Msgs[i].msg;
608  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
609  fatal_posix_service_status( status, -1, "mq_send error return status");
610  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
611
612  return i-1;
613}
614
615void validate_mq_receive_error_codes( )
616{
617  int            status;
618  char           message[100];
619  unsigned int   priority;
620
621  Start_Test( "mq_receive errors"  );
622
623  /*
624   * EBADF - Not A Valid Message Queue
625   */
626
627  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
628  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
629  fatal_posix_service_status( status, -1, "mq_ error return status");
630  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
631
632  /*
633   * EBADF - Queue not opened to read
634   */
635
636  puts( "Init: mq_receive - Write only queue (EBADF)" );
637  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
638  fatal_posix_service_status( status, -1, "mq_ error return status");
639  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
640
641  /*
642   * EMSGSIZE - Size is less than the message size attribute
643   */
644
645  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
646  status = mq_receive(
647    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
648  fatal_posix_service_status( status, -1, "mq_ error return status");
649  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
650
651
652  /*
653   * EAGAIN - O_NONBLOCK and Queue is empty
654   */
655  verify_queues_full( "Init:" );
656  empty_message_queues( "Init:" );
657
658  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
659  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
660  fatal_posix_service_status( status, -1, "mq_ error return status");
661  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
662
663  /*
664   * XXX - EINTR - Interrupted by a signal
665   */
666
667  /*
668   * XXX - EBADMSG - a data corruption problem.
669   */
670
671  /*
672   * XXX - ENOSYS - mq_receive not supported
673   */
674}
675
676void verify_open_functionality()
677{
678#if 0
679  mqd_t           n_mq;
680#endif
681
682  Start_Test( "mq_open functionality" );
683
684  /*
685   * Validate a second open returns the same message queue.
686   */
687
688#if 0
689  puts( "Init: mq_open - Open an existing mq ( same id )" );
690  n_mq = mq_open( RD_NAME, 0 );
691  fatal_posix_service_status(
692    (int) n_mq, (int ) Test_q[RD_QUEUE].mq, "mq_open error return status" );
693#endif
694}
695
696void verify_unlink_functionality()
697{
698  mqd_t           n_mq;
699  int             status;
700
701  Start_Test( "mq_unlink functionality" );
702
703  /*
704   * Unlink the message queue, then verify an open of the same name produces a
705   * different message queue.
706   */
707
708  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
709  status = mq_unlink( DEFAULT_NAME );
710  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
711
712  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
713  assert( n_mq != (-1) );
714  assert( n_mq != Test_q[ DEFAULT_RW ].mq );
715
716
717  status = mq_unlink( DEFAULT_NAME );
718  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
719  status = mq_close( Test_q[ DEFAULT_RW ].mq );
720  fatal_posix_service_status( status, 0, "mq_close message queue");
721
722  Test_q[ DEFAULT_RW ].mq = n_mq;
723}
724
725void verify_close_functionality()
726{
727  int i;
728  int status;
729  Start_Test( "Unlink and Close All Files"  );
730  for (i=0; i<DEFAULT_RW; i++) {
731
732    status = mq_unlink( Get_Queue_Name(i) );
733    fatal_posix_service_status( status, 0, "mq_unlink message queue");
734
735    status = mq_close( Test_q[i].mq );
736    fatal_posix_service_status( status, 0, "mq_close message queue");
737  }
738}
739
740
741void verify_timed_send_queue(
742  int  que,
743  int  is_blocking
744)
745{
746  struct timespec timeout;
747  struct timeval  tv1, tv2, tv3;
748  struct timezone tz1, tz2;
749  int              len;
750  int              status;
751  char            *msg;
752
753  timeout.tv_sec  = 1;
754  timeout.tv_nsec = 0;
755
756  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
757  len = Predefined_Msgs[MAXMSG].size;
758  msg = Predefined_Msgs[MAXMSG].msg;
759  gettimeofday( &tv1, &tz1 );
760  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
761  gettimeofday( &tv2, &tz2 );
762  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
763  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
764
765  if ( is_blocking ) { /* Don't verify the non-blocking queue */
766    fatal_int_service_status( status, -1, "mq_timedsend status");
767    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
768  }
769
770  printf("Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
771
772  if ( is_blocking ) /* non-blocking queue */
773    assert( tv3.tv_sec == 1 );
774  else
775    assert( tv3.tv_sec == 0 );
776
777  if ( que == DEFAULT_RW )
778    Test_q[que].count++;
779}
780
781void verify_timed_send()
782{
783  int              que;
784
785  Start_Test( "mq_timedsend"  );
786
787  for( que = RW_QUEUE; que < CLOSED; que++ ) {
788    if ( que == BLOCKING )
789      verify_timed_send_queue( que, 1 );
790    else
791      verify_timed_send_queue( que, 0 );
792  }
793}
794
795void verify_timed_receive_queue(
796  char *task_name,
797  int   que,
798  int   is_blocking
799)
800{
801  char message[ 100 ];
802  unsigned int priority;
803  struct timespec tm;
804  struct timeval  tv1, tv2, tv3;
805  struct timezone tz1, tz2;
806  int              status;
807
808  tm.tv_sec  = 1;
809  tm.tv_nsec = 0;
810
811  printf( "Init: %s mq_timedreceive - on queue %s ", task_name, Test_q[que].name);
812
813  gettimeofday( &tv1, &tz1 );
814  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
815  gettimeofday( &tv2, &tz2 );
816  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
817  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
818
819  fatal_int_service_status( status, -1, "mq_timedreceive status");
820  if ( is_blocking )
821    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
822  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
823
824  if ( is_blocking )
825    assert( tv3.tv_sec == 1 );
826  else
827    assert( tv3.tv_sec == 0 );
828}
829
830
831
832void verify_timed_receive()
833{
834  int  que;
835
836  Start_Test( "mq_timedreceive"  );
837
838  for( que = RW_QUEUE; que < CLOSED; que++ ) {
839    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
840      verify_timed_receive_queue( "Init:", que, 1 );
841    else
842      verify_timed_receive_queue( "Init:", que, 0 );
843  }
844}
845
846#if (0)
847void verify_set_attr()
848{
849  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
850  struct mq_attr attr;
851  int            i;
852  int            status;
853
854  attr.mq_maxmsg  = 0;
855  attr.mq_msgsize = 0;
856
857  Start_Test( "mq_setattr"  );
858
859  puts( "Init: set_attr all queues to blocking" );
860  for(i=0; i<CLOSED; i++) {
861    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
862    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
863    fatal_int_service_status( status, 0, "mq_setattr valid return status");
864
865    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
866  }
867
868  for( i = RW_QUEUE; i < CLOSED; i++ ) {
869    verify_timed_receive_queue( "Init:", i, 1 );
870  }
871
872  for(i=0; i<CLOSED; i++) {
873    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
874    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
875    fatal_int_service_status( status, 0, "mq_setattr valid return status");
876
877    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
878  }
879}
880#endif
881
882void wait_for_signal(
883  sigset_t     *waitset,
884  int           sec,
885  int           expect_signal
886)
887{
888  siginfo_t         siginfo;
889  int               status;
890  struct timespec   timeout;
891  int               signo;
892
893  siginfo.si_code = -1;
894  siginfo.si_signo = -1;
895  siginfo.si_value.sival_int = -1;
896
897  timeout.tv_sec = sec;
898  timeout.tv_nsec = 0;
899
900  status = sigemptyset( waitset );
901  assert( !status );
902
903  status = sigaddset( waitset, SIGUSR1 );
904  assert( !status );
905
906  printf( "waiting on any signal for %d seconds.\n", sec );
907  signo = sigtimedwait( waitset, &siginfo, &timeout );
908  if (expect_signal) {
909    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
910  } else {
911    fatal_int_service_status( signo, -1, "error return status");
912    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
913  }
914}
915
916void verify_notify()
917{
918  struct sigevent event;
919  int             status;
920  timer_t         timer_id;
921  sigset_t        set;
922
923  Start_Test( "mq_notify"  );
924
925  /* timer create */
926  event.sigev_notify = SIGEV_SIGNAL;
927  event.sigev_signo  = SIGUSR1;
928  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
929    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
930
931  /* block the timer signal */
932  sigemptyset( &set );
933  sigaddset( &set, SIGUSR1 );
934  pthread_sigmask( SIG_BLOCK, &set, NULL );
935
936  /*
937   * EBADF - Not A Valid Message Queue
938   */
939
940  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
941  status = mq_notify( Test_q[CLOSED].mq, NULL );
942  fatal_posix_service_status( status, -1, "mq_ error return status");
943  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
944
945  /*
946   * Create ...
947   */
948
949  /*
950   * XXX setup notification
951   */
952
953  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
954  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
955  fatal_posix_service_status( status, 0, "mq_notify valid status");
956  wait_for_signal( &set, 3, 0 );
957
958  /*
959   * Send and verify signal occurs and registration is removed.
960   */
961
962  puts( "Init: Verify Signal when send" );
963  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
964  wait_for_signal( &set, 3, 1 );
965  Read_msg_from_que( RW_QUEUE, 0 );
966
967  puts( "Init: Verify No Signal when send" );
968  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
969  wait_for_signal( &set, 3, 0 );
970  Read_msg_from_que( RW_QUEUE, 0 );
971
972
973  /*
974   * EBUSY - Already Registered
975   */
976
977  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
978  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
979  fatal_posix_service_status( status, 0, "mq_notify valid status");
980  wait_for_signal( &set, 3, 0 );
981
982  puts( "Init: mq_notify -  (EBUSY)" );
983  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
984  fatal_posix_service_status( status, -1, "mq_notify error return status");
985  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
986
987  /*
988   * Verify NULL removes registration.
989   */
990
991  puts( "Init: mq_notify - Remove notification with null" );
992  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
993  fatal_posix_service_status( status, 0, "mq_notify valid status");
994
995  puts( "Init: Verify No Signal when send" );
996  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
997  wait_for_signal( &set, 3, 0 );
998  Read_msg_from_que( RW_QUEUE, 0 );
999
1000}
1001
1002void verify_with_threads()
1003{
1004  int               status;
1005  pthread_t         id;
1006  Test_Message_t   *ptr;
1007#if 0
1008  unsigned int      priority;
1009  char              message[100];
1010#endif
1011
1012
1013#if 0
1014  /*
1015   * Create a task then block until the task sends the message.
1016   * Task tests set attributes so one queue will have a thread
1017   * blocked while attributes are changed.
1018   */
1019
1020  Start_Test( "multi-thread Task 4 Receive Test"  );
1021  status = pthread_create( &id, NULL, Task_4, NULL );
1022  assert( !status );
1023  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
1024  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
1025  fatal_int_service_status( status, -1, "mq_receive error return status");
1026  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
1027  print_current_time( "Init: ", "" );
1028#endif
1029  /*
1030   * Create a task then block until the task sends the message.
1031   * Task tests set attributes so one queue will have a thread
1032   * blocked while attributes are changed.
1033   */
1034
1035  Start_Test( "multi-thread Task 1 Test"  );
1036  status = pthread_create( &id, NULL, Task_1, NULL );
1037  assert( !status );
1038  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
1039  print_current_time( "Init: ", "" );
1040
1041#if 0
1042  /*
1043   * Fill the queue then create a task then block until the task receives a message.
1044   * Task tests set attributes so one queue will have a thread
1045   * blocked while attributes are changed.
1046   */
1047
1048  Start_Test( "multi-thread Task 4 Send Test"  );
1049  fill_message_queues( "Init:" );
1050  status = pthread_create( &id, NULL, Task_4, NULL );
1051  assert( !status );
1052  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
1053  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
1054  fatal_posix_service_status( status, -1, "mq_send error return status");
1055  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
1056  verify_queues_full( "Init:" );
1057  empty_message_queues( "Init:" );
1058#endif
1059  /*
1060   * Create a task then block until the task reads a message.
1061   */
1062
1063  Start_Test( "multi-thread Task 2 Test"  );
1064  fill_message_queues( "Init:" );
1065  status = pthread_create( &id, NULL, Task_2, NULL );
1066  assert( !status );
1067  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
1068  print_current_time( "Init: ", "" );
1069  verify_queues_full( "Init:" );
1070  empty_message_queues( "Init:" );
1071
1072  /*
1073   * Create a task then block until it deletes and closes all queues.
1074   *     EBADF - Queue unlinked and closed while blocked
1075   */
1076
1077  Start_Test( "multi-thread Task 3 Test"  );
1078  fill_message_queues( "Init:" );
1079  status = pthread_create( &id, NULL, Task_3, NULL );
1080  assert( !status );
1081  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
1082  ptr = &Predefined_Msgs[0];
1083  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
1084  fatal_posix_service_status( status, -1, "mq_send error return status");
1085  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
1086
1087}
1088
1089void validate_mq_setattr()
1090{
1091  struct mq_attr  attr;
1092  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
1093  int             status;
1094  int            i;
1095
1096  /*
1097   * EBADF - Get the attributes from a closed queue.
1098   */
1099
1100  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
1101  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
1102  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1103  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF");
1104
1105  /*
1106   * XXX - The following are not listed in the POSIX manual but
1107   *       may occur.
1108   */
1109
1110  /*
1111   * EINVAL - NULL attributes
1112   */
1113
1114  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
1115  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
1116  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1117  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL");
1118
1119  /*
1120   * Verify change queues to blocking, by verifying all queues block
1121   * for a timed receive.
1122   */
1123
1124  puts( "Init: set_attr all queues to blocking" );
1125  for(i=0; i<CLOSED; i++) {
1126    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
1127    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
1128    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1129    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
1130  }
1131  for( i = RW_QUEUE; i < CLOSED; i++ ) {
1132    verify_timed_receive_queue( "Init:", i, 1 );
1133  }
1134
1135  /*
1136   * Restore restore all queues to their old attribute.
1137   */
1138
1139  for(i=0; i<CLOSED; i++) {
1140    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
1141    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1142    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
1143  }
1144}
1145
1146void *POSIX_Init(
1147  void *argument
1148)
1149{
1150  puts( "\n\n*** POSIX MESSAGE QUEUE TEST ***" );
1151
1152  validate_mq_open_error_codes( );
1153  open_test_queues();
1154  validate_mq_unlink_error_codes();
1155  validate_mq_close_error_codes();
1156  verify_unlink_functionality();
1157  validate_mq_setattr( );
1158  validate_mq_send_error_codes();
1159  validate_mq_getattr_error_codes();
1160  verify_timed_send();
1161  validate_mq_receive_error_codes();
1162  verify_timed_receive();
1163  verify_open_functionality();
1164  verify_notify();
1165  verify_with_threads();
1166
1167  puts( "*** END OF POSIX MESSAGE QUEUE TEST ***" );
1168  rtems_test_exit( 0 );
1169
1170  return NULL; /* just so the compiler thinks we returned something */
1171}
1172
1173
1174void *Task_1 (
1175  void *argument
1176)
1177{
1178  /* Block Waiting for a message */
1179
1180  print_current_time( "Task_1: ", "" );
1181
1182  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
1183
1184  puts( "Task_1: pthread_exit" );
1185  pthread_exit( NULL );
1186
1187  /* switch to Init */
1188
1189  assert( 0 );
1190  return NULL; /* just so the compiler thinks we returned something */
1191}
1192
1193void *Task_2(
1194  void *argument
1195)
1196{
1197  print_current_time( "Task_2: ", "" );
1198
1199
1200  /* Block waiting to send a message */
1201
1202  verify_queues_full( "Task_2:" );
1203  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
1204
1205  puts( "Task_2: pthread_exit" );
1206  pthread_exit( NULL );
1207
1208     /* switch to Init */
1209
1210  return NULL; /* just so the compiler thinks we returned something */
1211}
1212
1213void *Task_3 (
1214  void *argument
1215)
1216{
1217
1218  print_current_time( "Task_3: ", "" );
1219
1220  /*
1221   * close and unlink all queues.
1222   */
1223
1224  verify_close_functionality( "Task_3: " );
1225  puts( "Task_3: pthread_exit" );
1226  pthread_exit( NULL );
1227
1228     /* switch to Init */
1229
1230  return NULL; /* just so the compiler thinks we returned something */
1231
1232}
1233
1234void *Task_4 (
1235  void *argument
1236)
1237{
1238  struct mq_attr  attr;
1239  int             status;
1240  int             count;
1241
1242  print_current_time( "Task_4: ", "" );
1243
1244  /*
1245   * Set the count to the number of messages in the queue.
1246   */
1247
1248  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
1249  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
1250  count = attr.mq_curmsgs;
1251
1252  puts("Task_4: Set queue to non-blocking");
1253  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
1254  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1255  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1256  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1257
1258  puts("Task_4: Return queue to blocking");
1259  attr.mq_flags =  Test_q[BLOCKING].oflag;
1260  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1261  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1262  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1263
1264  puts( "Task_4: pthread_exit" );
1265  pthread_exit( NULL );
1266
1267     /* switch to Init */
1268
1269  return NULL; /* just so the compiler thinks we returned something */
1270
1271}
1272
1273void *Task_5 (
1274  void *argument
1275)
1276{
1277
1278  print_current_time( "Task_5: ", "" );
1279
1280  puts( "Task_5: pthread_exit" );
1281  pthread_exit( NULL );
1282
1283     /* switch to Init */
1284
1285  return NULL; /* just so the compiler thinks we returned something */
1286
1287}
1288
1289void *Task_ (
1290  void *argument
1291)
1292{
1293
1294  print_current_time( "Task_: ", "" );
1295
1296  puts( "Task_: pthread_exit" );
1297  pthread_exit( NULL );
1298
1299     /* switch to Init */
1300
1301  return NULL; /* just so the compiler thinks we returned something */
1302
1303}
Note: See TracBrowser for help on using the repository browser.