source: rtems/testsuites/psxtests/psxmsgq01/init.c @ 1750f5a6

Last change on this file since 1750f5a6 was 1750f5a6, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 24, 2008 at 8:43:58 PM

2008-07-24 Joel Sherrill <joel.sherrill@…>

PR 1291/cpukit

  • psx05/init.c, psxmsgq01/init.c, psxmsgq01/system.h, psxsem01/init.c, psxsem01/psxsem01.scn: Update tests to reflect changes required by problem.
  • Property mode set to 100644
File size: 34.2 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  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
754  len = Predefined_Msgs[MAXMSG].size;
755  msg = Predefined_Msgs[MAXMSG].msg;
756
757  gettimeofday( &tv1, &tz1 );
758  timeout.tv_sec  = tv1.tv_sec + 1;
759  timeout.tv_nsec = tv1.tv_usec * 1000;
760
761  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
762
763  gettimeofday( &tv2, &tz2 );
764  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
765  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
766
767  if ( is_blocking ) { /* Don't verify the non-blocking queue */
768    fatal_int_service_status( status, -1, "mq_timedsend status" );
769    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT" );
770  }
771
772  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
773
774  if ( que == DEFAULT_RW )
775    Test_q[que].count++;
776}
777
778void verify_timed_send()
779{
780  int              que;
781
782  Start_Test( "mq_timedsend"  );
783
784  for( que = RW_QUEUE; que < CLOSED; que++ ) {
785    if ( que == BLOCKING )
786      verify_timed_send_queue( que, 1 );
787    else
788      verify_timed_send_queue( que, 0 );
789  }
790}
791
792void verify_timed_receive_queue(
793  char *task_name,
794  int   que,
795  int   is_blocking
796)
797{
798  char message[ 100 ];
799  unsigned int priority;
800  struct timespec tm;
801  struct timeval  tv1, tv2, tv3;
802  struct timezone tz1, tz2;
803  int              status;
804
805  printf(
806    "Init: %s mq_timedreceive - on queue %s ",
807    task_name,
808    Test_q[que].name
809  );
810
811  gettimeofday( &tv1, &tz1 );
812  tm.tv_sec  = tv1.tv_sec + 1;
813  tm.tv_nsec = tv1.tv_usec * 1000;
814
815  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
816
817  gettimeofday( &tv2, &tz2 );
818  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
819  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
820
821  fatal_int_service_status( status, -1, "mq_timedreceive status");
822  if ( is_blocking )
823    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
824  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
825
826}
827
828void verify_timed_receive()
829{
830  int  que;
831
832  Start_Test( "mq_timedreceive"  );
833
834  for( que = RW_QUEUE; que < CLOSED; que++ ) {
835    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
836      verify_timed_receive_queue( "Init:", que, 1 );
837    else
838      verify_timed_receive_queue( "Init:", que, 0 );
839  }
840}
841
842#if (0)
843void verify_set_attr()
844{
845  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
846  struct mq_attr attr;
847  int            i;
848  int            status;
849
850  attr.mq_maxmsg  = 0;
851  attr.mq_msgsize = 0;
852
853  Start_Test( "mq_setattr"  );
854
855  puts( "Init: set_attr all queues to blocking" );
856  for(i=0; i<CLOSED; i++) {
857    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
858    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
859    fatal_int_service_status( status, 0, "mq_setattr valid return status");
860
861    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
862  }
863
864  for( i = RW_QUEUE; i < CLOSED; i++ ) {
865    verify_timed_receive_queue( "Init:", i, 1 );
866  }
867
868  for(i=0; i<CLOSED; i++) {
869    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
870    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
871    fatal_int_service_status( status, 0, "mq_setattr valid return status");
872
873    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
874  }
875}
876#endif
877
878void wait_for_signal(
879  sigset_t     *waitset,
880  int           sec,
881  int           expect_signal
882)
883{
884  siginfo_t         siginfo;
885  int               status;
886  struct timespec   timeout;
887  int               signo;
888
889  siginfo.si_code = -1;
890  siginfo.si_signo = -1;
891  siginfo.si_value.sival_int = -1;
892
893  timeout.tv_sec = sec;
894  timeout.tv_nsec = 0;
895
896  status = sigemptyset( waitset );
897  assert( !status );
898
899  status = sigaddset( waitset, SIGUSR1 );
900  assert( !status );
901
902  printf( "waiting on any signal for %d seconds.\n", sec );
903  signo = sigtimedwait( waitset, &siginfo, &timeout );
904  if (expect_signal) {
905    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
906  } else {
907    fatal_int_service_status( signo, -1, "error return status");
908    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
909  }
910}
911
912void verify_notify()
913{
914  struct sigevent event;
915  int             status;
916  timer_t         timer_id;
917  sigset_t        set;
918
919  Start_Test( "mq_notify"  );
920
921  /* timer create */
922  event.sigev_notify = SIGEV_SIGNAL;
923  event.sigev_signo  = SIGUSR1;
924  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
925    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
926
927  /* block the timer signal */
928  sigemptyset( &set );
929  sigaddset( &set, SIGUSR1 );
930  pthread_sigmask( SIG_BLOCK, &set, NULL );
931
932  /*
933   * EBADF - Not A Valid Message Queue
934   */
935
936  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
937  status = mq_notify( Test_q[CLOSED].mq, NULL );
938  fatal_posix_service_status( status, -1, "mq_ error return status");
939  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
940
941  /*
942   * Create ...
943   */
944
945  /*
946   * XXX setup notification
947   */
948
949  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
950  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
951  fatal_posix_service_status( status, 0, "mq_notify valid status");
952  wait_for_signal( &set, 3, 0 );
953
954  /*
955   * Send and verify signal occurs and registration is removed.
956   */
957
958  puts( "Init: Verify Signal when send" );
959  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
960  wait_for_signal( &set, 3, 1 );
961  Read_msg_from_que( RW_QUEUE, 0 );
962
963  puts( "Init: Verify No Signal when send" );
964  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
965  wait_for_signal( &set, 3, 0 );
966  Read_msg_from_que( RW_QUEUE, 0 );
967
968
969  /*
970   * EBUSY - Already Registered
971   */
972
973  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
974  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
975  fatal_posix_service_status( status, 0, "mq_notify valid status");
976  wait_for_signal( &set, 3, 0 );
977
978  puts( "Init: mq_notify -  (EBUSY)" );
979  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
980  fatal_posix_service_status( status, -1, "mq_notify error return status");
981  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
982
983  /*
984   * Verify NULL removes registration.
985   */
986
987  puts( "Init: mq_notify - Remove notification with null" );
988  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
989  fatal_posix_service_status( status, 0, "mq_notify valid status");
990
991  puts( "Init: Verify No Signal when send" );
992  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
993  wait_for_signal( &set, 3, 0 );
994  Read_msg_from_que( RW_QUEUE, 0 );
995
996}
997
998void verify_with_threads()
999{
1000  int               status;
1001  pthread_t         id;
1002  Test_Message_t   *ptr;
1003#if 0
1004  unsigned int      priority;
1005  char              message[100];
1006#endif
1007
1008
1009#if 0
1010  /*
1011   * Create a task then block until the task sends the message.
1012   * Task tests set attributes so one queue will have a thread
1013   * blocked while attributes are changed.
1014   */
1015
1016  Start_Test( "multi-thread Task 4 Receive Test"  );
1017  status = pthread_create( &id, NULL, Task_4, NULL );
1018  assert( !status );
1019  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
1020  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
1021  fatal_int_service_status( status, -1, "mq_receive error return status");
1022  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
1023  print_current_time( "Init: ", "" );
1024#endif
1025  /*
1026   * Create a task then block until the task sends the message.
1027   * Task tests set attributes so one queue will have a thread
1028   * blocked while attributes are changed.
1029   */
1030
1031  Start_Test( "multi-thread Task 1 Test"  );
1032  status = pthread_create( &id, NULL, Task_1, NULL );
1033  assert( !status );
1034  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
1035  print_current_time( "Init: ", "" );
1036
1037#if 0
1038  /*
1039   * Fill the queue then create a task then block until the task receives a message.
1040   * Task tests set attributes so one queue will have a thread
1041   * blocked while attributes are changed.
1042   */
1043
1044  Start_Test( "multi-thread Task 4 Send Test"  );
1045  fill_message_queues( "Init:" );
1046  status = pthread_create( &id, NULL, Task_4, NULL );
1047  assert( !status );
1048  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
1049  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
1050  fatal_posix_service_status( status, -1, "mq_send error return status");
1051  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
1052  verify_queues_full( "Init:" );
1053  empty_message_queues( "Init:" );
1054#endif
1055  /*
1056   * Create a task then block until the task reads a message.
1057   */
1058
1059  Start_Test( "multi-thread Task 2 Test"  );
1060  fill_message_queues( "Init:" );
1061  status = pthread_create( &id, NULL, Task_2, NULL );
1062  assert( !status );
1063  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
1064  print_current_time( "Init: ", "" );
1065  verify_queues_full( "Init:" );
1066  empty_message_queues( "Init:" );
1067
1068  /*
1069   * Create a task then block until it deletes and closes all queues.
1070   *     EBADF - Queue unlinked and closed while blocked
1071   */
1072
1073  Start_Test( "multi-thread Task 3 Test"  );
1074  fill_message_queues( "Init:" );
1075  status = pthread_create( &id, NULL, Task_3, NULL );
1076  assert( !status );
1077  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
1078  ptr = &Predefined_Msgs[0];
1079  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
1080  fatal_posix_service_status( status, -1, "mq_send error return status");
1081  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
1082
1083}
1084
1085void validate_mq_setattr()
1086{
1087  struct mq_attr  attr;
1088  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
1089  int             status;
1090  int            i;
1091
1092  /*
1093   * EBADF - Get the attributes from a closed queue.
1094   */
1095
1096  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
1097  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
1098  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1099  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF");
1100
1101  /*
1102   * XXX - The following are not listed in the POSIX manual but
1103   *       may occur.
1104   */
1105
1106  /*
1107   * EINVAL - NULL attributes
1108   */
1109
1110  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
1111  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
1112  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1113  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL");
1114
1115  /*
1116   * Verify change queues to blocking, by verifying all queues block
1117   * for a timed receive.
1118   */
1119
1120  puts( "Init: set_attr all queues to blocking" );
1121  for(i=0; i<CLOSED; i++) {
1122    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
1123    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
1124    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1125    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
1126  }
1127  for( i = RW_QUEUE; i < CLOSED; i++ ) {
1128    verify_timed_receive_queue( "Init:", i, 1 );
1129  }
1130
1131  /*
1132   * Restore restore all queues to their old attribute.
1133   */
1134
1135  for(i=0; i<CLOSED; i++) {
1136    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
1137    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1138    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
1139  }
1140}
1141
1142void *POSIX_Init(
1143  void *argument
1144)
1145{
1146  puts( "\n\n*** POSIX MESSAGE QUEUE TEST ***" );
1147
1148  validate_mq_open_error_codes( );
1149  open_test_queues();
1150  validate_mq_unlink_error_codes();
1151  validate_mq_close_error_codes();
1152  verify_unlink_functionality();
1153  validate_mq_setattr( );
1154  validate_mq_send_error_codes();
1155  validate_mq_getattr_error_codes();
1156  verify_timed_send();
1157  validate_mq_receive_error_codes();
1158  verify_timed_receive();
1159  verify_open_functionality();
1160  verify_notify();
1161  verify_with_threads();
1162
1163  puts( "*** END OF POSIX MESSAGE QUEUE TEST ***" );
1164  rtems_test_exit( 0 );
1165
1166  return NULL; /* just so the compiler thinks we returned something */
1167}
1168
1169
1170void *Task_1 (
1171  void *argument
1172)
1173{
1174  /* Block Waiting for a message */
1175
1176  print_current_time( "Task_1: ", "" );
1177
1178  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
1179
1180  puts( "Task_1: pthread_exit" );
1181  pthread_exit( NULL );
1182
1183  /* switch to Init */
1184
1185  assert( 0 );
1186  return NULL; /* just so the compiler thinks we returned something */
1187}
1188
1189void *Task_2(
1190  void *argument
1191)
1192{
1193  print_current_time( "Task_2: ", "" );
1194
1195
1196  /* Block waiting to send a message */
1197
1198  verify_queues_full( "Task_2:" );
1199  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
1200
1201  puts( "Task_2: pthread_exit" );
1202  pthread_exit( NULL );
1203
1204     /* switch to Init */
1205
1206  return NULL; /* just so the compiler thinks we returned something */
1207}
1208
1209void *Task_3 (
1210  void *argument
1211)
1212{
1213
1214  print_current_time( "Task_3: ", "" );
1215
1216  /*
1217   * close and unlink all queues.
1218   */
1219
1220  verify_close_functionality( "Task_3: " );
1221  puts( "Task_3: pthread_exit" );
1222  pthread_exit( NULL );
1223
1224     /* switch to Init */
1225
1226  return NULL; /* just so the compiler thinks we returned something */
1227
1228}
1229
1230void *Task_4 (
1231  void *argument
1232)
1233{
1234  struct mq_attr  attr;
1235  int             status;
1236  int             count;
1237
1238  print_current_time( "Task_4: ", "" );
1239
1240  /*
1241   * Set the count to the number of messages in the queue.
1242   */
1243
1244  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
1245  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
1246  count = attr.mq_curmsgs;
1247
1248  puts("Task_4: Set queue to non-blocking");
1249  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
1250  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1251  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1252  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1253
1254  puts("Task_4: Return queue to blocking");
1255  attr.mq_flags =  Test_q[BLOCKING].oflag;
1256  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1257  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1258  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1259
1260  puts( "Task_4: pthread_exit" );
1261  pthread_exit( NULL );
1262
1263     /* switch to Init */
1264
1265  return NULL; /* just so the compiler thinks we returned something */
1266
1267}
1268
1269void *Task_5 (
1270  void *argument
1271)
1272{
1273
1274  print_current_time( "Task_5: ", "" );
1275
1276  puts( "Task_5: pthread_exit" );
1277  pthread_exit( NULL );
1278
1279     /* switch to Init */
1280
1281  return NULL; /* just so the compiler thinks we returned something */
1282
1283}
1284
1285void *Task_ (
1286  void *argument
1287)
1288{
1289
1290  print_current_time( "Task_: ", "" );
1291
1292  puts( "Task_: pthread_exit" );
1293  pthread_exit( NULL );
1294
1295     /* switch to Init */
1296
1297  return NULL; /* just so the compiler thinks we returned something */
1298
1299}
Note: See TracBrowser for help on using the repository browser.