Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:40

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2012.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #define CONFIGURE_INIT
0034 #include "system.h"
0035 #include <sched.h>
0036 #include <fcntl.h>
0037 #include <time.h>
0038 #include <tmacros.h>
0039 #include <signal.h>   /* signal facilities */
0040 #include "test_support.h"
0041 
0042 const char rtems_test_name[] = "PSXMSGQ 1";
0043 
0044 /* forward declarations to avoid warnings */
0045 void Start_Test(char *description);
0046 void Validate_attributes(mqd_t mq, int oflag, int msg_count);
0047 char *Build_Queue_Name(int i);
0048 void open_test_queues(void);
0049 void validate_mq_open_error_codes(void);
0050 void validate_mq_unlink_error_codes(void);
0051 void validate_mq_close_error_codes(void);
0052 void validate_mq_getattr_error_codes(void);
0053 void Send_msg_to_que(int que, int msg);
0054 void Show_send_msg_to_que(char *task_name, int que, int msg);
0055 void verify_queues_full(char *task_name);
0056 void verify_queues_empty(char *task_name);
0057 int empty_message_queues(char *task_name);
0058 int fill_message_queues(char *task_name);
0059 void Read_msg_from_que(int que, int msg);
0060 int validate_mq_send_error_codes(void);
0061 void validate_mq_receive_error_codes(void);
0062 void verify_open_functionality(void);
0063 void verify_unlink_functionality(void);
0064 void verify_close_functionality(void);
0065 void verify_timed_send_queue(int que, int is_blocking);
0066 void verify_timed_send(void);
0067 void verify_timed_receive_queue(char *task_name, int que, int is_blocking);
0068 void verify_timed_receive(void);
0069 void wait_for_signal(sigset_t *waitset, int sec, int expect_signal);
0070 void verify_notify(void);
0071 void verify_with_threads(void);
0072 void verify_timedout_mq_timedreceive(char *task_name, int que, int is_blocking);
0073 void verify_timedout_mq_timedsend(int que, int is_blocking);
0074 void verify_timed_receive(void);
0075 void validate_mq_setattr(void);
0076 void verify_timedout_mq_timedreceive(
0077   char *task_name, int que, int is_blocking);
0078 void verify_mq_receive(void);
0079 void verify_timedout_mq_timedsend(int que, int is_blocking);
0080 void verify_mq_send(void);
0081 void verify_timed_receive(void);
0082 
0083 typedef struct {
0084   char         msg[ 50 ];
0085   int          size;
0086   unsigned int priority;
0087 } Test_Message_t;
0088 
0089 Test_Message_t Predefined_Msgs[MAXMSG+1];
0090 Test_Message_t Predefined_Msgs[MAXMSG+1] = {
0091   { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
0092   { "",           1, 1             },  /* NULL  Message      low  */
0093   { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */
0094   { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
0095   { "1",          2, 0             },  /* Cause Overflow Behavior */
0096 };
0097 int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
0098 
0099 
0100 typedef struct {
0101   mqd_t              mq;
0102   Test_Queue_Types   index;
0103   char              *name;
0104   int                oflag;
0105   int                maxmsg;
0106   int                msgsize;
0107   int                count;
0108 } Test_queue_type;
0109 
0110 Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES + 1 ] =
0111 {
0112   { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
0113   { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
0114   { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
0115   { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
0116   { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
0117   { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
0118   { 0, 6, "Qblock",   (           O_RDWR )               , MAXMSG, MSGSIZE, 0 },
0119 };
0120 
0121 #define RW_NAME             Test_q[ RW_QUEUE ].name
0122 #define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
0123 #define RD_NAME             Test_q[ RD_QUEUE ].name
0124 #define WR_NAME             Test_q[ WR_QUEUE ].name
0125 #define BLOCKING_NAME       Test_q[ BLOCKING ].name
0126 #define CLOSED_NAME         Test_q[ CLOSED ].name
0127 
0128 #define RW_ATTR         Test_q[ RW_QUEUE ].oflag
0129 #define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
0130 #define RD_ATTR         Test_q[ RD_QUEUE ].oflag
0131 #define WR_ATTR         Test_q[ WR_QUEUE ].oflag
0132 #define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
0133 #define CLOSED_ATTR     Test_q[ CLOSED ].oflag
0134 
0135 /*
0136  * Outputs a header at each test section.
0137  */
0138 void Start_Test(
0139   char *description
0140 )
0141 {
0142   printf( "_______________%s\n", description );
0143 }
0144 
0145 
0146 void Validate_attributes(
0147   mqd_t  mq,
0148   int    oflag,
0149   int    msg_count
0150 )
0151 {
0152   int             status;
0153   struct mq_attr  attr;
0154 
0155   status = mq_getattr( mq, &attr );
0156   fatal_posix_service_status( status, 0, "mq_getattr valid return status");
0157 
0158   if ( mq != Test_q[ DEFAULT_RW ].mq ){
0159     fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
0160     fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
0161   }
0162 
0163   fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
0164   fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
0165 }
0166 
0167 #define Get_Queue_Name( i )  Test_q[i].name
0168 char *Build_Queue_Name(int i)
0169 {
0170   static char Queue_Name[PATH_MAX + 2];
0171 
0172   sprintf(Queue_Name,"mq%d", i+1 );
0173   return Queue_Name;
0174 }
0175 
0176 void open_test_queues(void)
0177 {
0178   struct mq_attr   attr;
0179   int              status;
0180   Test_queue_type *tq;
0181   int              que;
0182 
0183   attr.mq_maxmsg  = MAXMSG;
0184   attr.mq_msgsize = MSGSIZE;
0185 
0186   puts( "Init: Open Test Queues" );
0187 
0188   for( que = 0; que < NUMBER_OF_TEST_QUEUES+1; que++ ) {
0189 
0190     tq = &Test_q[ que ];
0191     if ( que == DEFAULT_RW)
0192       Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
0193     else
0194       Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
0195 
0196     rtems_test_assert( Test_q[que].mq != (-1) );
0197   }
0198 
0199   status = mq_close( Test_q[NUMBER_OF_TEST_QUEUES].mq );
0200   fatal_posix_service_status( status, 0, "mq_close duplicate message queue");
0201   status = mq_close( Test_q[CLOSED].mq );
0202   fatal_posix_service_status( status, 0, "mq_close message queue");
0203   status = mq_unlink( CLOSED_NAME );
0204   fatal_posix_service_status( status, 0, "mq_unlink message queue");
0205 }
0206 
0207 /*
0208  * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues
0209  * opened but closes the rest.
0210  */
0211 
0212 void validate_mq_open_error_codes(void)
0213 {
0214   int             i;
0215   mqd_t           n_mq2;
0216   struct mq_attr  attr;
0217   int             status;
0218   mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1];
0219 
0220   attr.mq_maxmsg  = MAXMSG;
0221   attr.mq_msgsize = MSGSIZE;
0222 
0223   Start_Test( "mq_open errors" );
0224 
0225   /*
0226    * XXX EINVAL - inappropriate name was given for the message queue
0227    */
0228 
0229   /*
0230    * EINVAL - Create with negative maxmsg.
0231    */
0232 
0233   attr.mq_maxmsg = -1;
0234   puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
0235   n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
0236   fatal_posix_mqd( n_mq2, "mq_open error return status" );
0237   fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
0238   attr.mq_maxmsg  = MAXMSG;
0239 
0240   /*
0241    * EINVAL - Create withnegative msgsize.
0242    */
0243 
0244   attr.mq_msgsize = -1;
0245   puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
0246   n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
0247   fatal_posix_mqd( n_mq2, "mq_open error return status" );
0248   fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
0249   attr.mq_msgsize = MSGSIZE;
0250 
0251   /*
0252    * ENOENT - Open a non-created file.
0253    */
0254 
0255   puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
0256   n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
0257   fatal_posix_mqd( n_mq2, "mq_open error return status" );
0258   fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
0259 
0260   /*
0261    * XXX EINTR  - call was interrupted by a signal
0262    */
0263 
0264   /*
0265    * ENAMETOOLONG - Give a name greater than PATH_MAX.
0266    */
0267 
0268   puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
0269   n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
0270   fatal_posix_mqd( n_mq2, "mq_open error return status" );
0271   fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
0272 
0273   /*
0274    * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
0275    *       Per implementation not possible.
0276    */
0277 
0278   /*
0279    * EEXIST - Create an existing queue.
0280    */
0281 
0282   puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
0283   open_mq[0] = mq_open(
0284     Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
0285   rtems_test_assert( open_mq[0] != (-1) );
0286 
0287   n_mq2 = mq_open(
0288     Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
0289   fatal_posix_mqd( n_mq2, "mq_open error return status" );
0290   fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
0291 
0292   status = mq_unlink( Build_Queue_Name(0) );
0293   fatal_posix_service_status( status, 0, "mq_unlink message queue");
0294 
0295   status = mq_close( open_mq[0]);
0296   fatal_posix_service_status( status, 0, "mq_close message queue");
0297 
0298   /*
0299    * Open maximum number of message queues
0300    */
0301 
0302   puts( "Init: mq_open - SUCCESSFUL" );
0303   for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
0304     open_mq[i] = mq_open(
0305       Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
0306     rtems_test_assert( open_mq[i] != (-1) );
0307     rtems_test_assert( open_mq[i] );
0308     /*XXX - Isn't there a more general check */
0309 /* JRS     printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
0310   }
0311 
0312   /*
0313    * XXX EACCES - permission to create is denied.
0314    */
0315 
0316   /*
0317    * XXX EACCES - queue exists permissions specified by o_flag are denied.
0318    */
0319 
0320   /*
0321    * XXX EMFILE  - Too many message queues in use by the process
0322    */
0323 
0324   /*
0325    * ENFILE -  Too many message queues open in the system
0326    */
0327 
0328   puts( "Init: mq_open - system is out of resources (ENFILE)" );
0329   n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
0330   fatal_posix_mqd( n_mq2, "mq_open error return status" );
0331   fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
0332 
0333   /*
0334    * Unlink and Close all queues.
0335    */
0336 
0337   puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
0338   for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
0339 
0340     status = mq_close( open_mq[i]);
0341     fatal_posix_service_status( status, 0, "mq_close message queue");
0342 
0343     status = mq_unlink( Build_Queue_Name(i) );
0344     if ( status == -1 )
0345       perror( "mq_unlink" );
0346     fatal_posix_service_status( status, 0, "mq_unlink message queue");
0347     /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
0348   }
0349 }
0350 
0351 void validate_mq_unlink_error_codes(void)
0352 {
0353   int             status;
0354 
0355   Start_Test( "mq_unlink errors" );
0356 
0357   /*
0358    * XXX - EACCES Permission Denied
0359    */
0360 
0361   /*
0362    * ENAMETOOLONG - Give a name greater than PATH_MAX.
0363    */
0364 
0365   puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
0366   status = mq_unlink( Get_Too_Long_Name() );
0367   fatal_posix_service_status( status, -1, "mq_unlink error return status");
0368   fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
0369 
0370   /*
0371    * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
0372    *       Per implementation not possible.
0373    */
0374 
0375   /*
0376    *  ENOENT - Unlink an unopened queue
0377    */
0378 
0379   puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
0380   status = mq_unlink( CLOSED_NAME );
0381   fatal_posix_service_status( status, -1, "mq_unlink error return status");
0382   fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
0383 
0384   /*
0385    * XXX - The following were not listed in the POSIX document as
0386    *       possible errors.  Under other commands the EINVAL is
0387    *       given for these conditions.
0388    */
0389 
0390   /*
0391    *  EINVAL - Unlink a queue with no name
0392    */
0393 
0394   puts( "Init: mq_unlink (NULL) - EINVAL" );
0395   status = mq_unlink( NULL );
0396   fatal_posix_service_status( status, -1, "mq_unlink error return status");
0397   fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
0398 
0399   /*
0400    *  ENOENT - Unlink a queue with a zero length name
0401    */
0402 
0403   puts( "Init: mq_unlink (\"\") - ENOENT" );
0404   status = mq_unlink( "" );
0405   fatal_posix_service_status( status, -1, "mq_unlink error return status");
0406   fatal_posix_service_status( errno, ENOENT, "mq_unlink errno value");
0407 }
0408 
0409 void validate_mq_close_error_codes(void)
0410 {
0411   int             status;
0412 
0413   Start_Test( "mq_close errors" );
0414 
0415   /*
0416    * EBADF - Close a queue that is not open.
0417    */
0418 
0419   puts( "Init: mq_close - unopened queue (EBADF)" );
0420   status = mq_close( Test_q[CLOSED].mq );
0421   fatal_posix_service_status( status, -1, "mq_close error return status");
0422   fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
0423 }
0424 
0425 
0426 void validate_mq_getattr_error_codes(void)
0427 {
0428   struct mq_attr  attr;
0429   int             status;
0430 
0431   Start_Test( "mq_getattr errors" );
0432 
0433   /*
0434    * EBADF - Get the attributes from a closed queue.
0435    */
0436 
0437   puts( "Init: mq_getattr - unopened queue (EBADF)" );
0438   status = mq_getattr( Test_q[CLOSED].mq, &attr );
0439   fatal_posix_service_status( status, -1, "mq_close error return status");
0440   fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
0441 
0442   /*
0443    * XXX - The following are not listed in the POSIX manual but
0444    *       may occur.
0445    */
0446 
0447   /*
0448    * EINVAL - NULL attributes
0449    */
0450 
0451   puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
0452   status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
0453   fatal_posix_service_status( status, -1, "mq_close error return status");
0454   fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL");
0455 
0456 }
0457 
0458 
0459 void Send_msg_to_que(
0460   int que,
0461   int msg
0462 )
0463 {
0464   Test_Message_t *ptr = &Predefined_Msgs[msg];
0465   int             status;
0466 
0467   status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
0468   fatal_posix_service_status( status, 0, "mq_send valid return status");
0469   Test_q[que].count++;
0470 }
0471 
0472 void Show_send_msg_to_que(
0473   char *task_name,
0474   int   que,
0475   int   msg
0476 )
0477 {
0478   Test_Message_t *ptr = &Predefined_Msgs[msg];
0479   printf( "%s mq_send -  to %s msg: %s priority %d\n",
0480     task_name, Test_q[que].name, ptr->msg, ptr->priority);
0481   Send_msg_to_que( que, msg );
0482 }
0483 
0484 void verify_queues_full(
0485   char *task_name
0486 )
0487 {
0488   int          que;
0489 
0490   /*
0491    * Validate that the queues are full.
0492    */
0493 
0494   printf( "%s Verify Queues are full\n", task_name );
0495   for( que = RW_QUEUE; que < CLOSED; que++ )
0496     Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
0497 
0498 }
0499 void verify_queues_empty(
0500   char *task_name
0501 )
0502 {
0503   int             que;
0504 
0505   printf( "%s Verify Queues are empty\n", task_name );
0506   for( que = RW_QUEUE; que < CLOSED; que++ )
0507     Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
0508 }
0509 
0510 int fill_message_queues(
0511   char *task_name
0512 )
0513 {
0514   int             msg;
0515   int             que;
0516 
0517 
0518   verify_queues_empty( task_name );
0519 
0520   /*
0521    * Fill Queue with predefined messages.
0522    */
0523 
0524   printf( "%s Fill Queues with messages\n", task_name );
0525   for(msg=0; msg<MAXMSG; msg++){
0526     for( que = RW_QUEUE; que < CLOSED; que++ ) {
0527       Send_msg_to_que( que, msg );
0528     }
0529   }
0530 
0531   verify_queues_full( "Init:" );
0532   return msg;
0533 }
0534 
0535 
0536 void Read_msg_from_que(
0537   int que,
0538   int msg
0539 )
0540 {
0541   unsigned int    priority;
0542   Test_Message_t *ptr;
0543   int             status;
0544   char            message[100];
0545   char            err_msg[100];
0546 
0547   ptr = &Predefined_Msgs[msg];
0548   status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
0549   Test_q[que].count--;
0550 
0551   sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
0552   fatal_int_service_status( status, ptr->size, err_msg );
0553 
0554   rtems_test_assert( !strcmp( message, ptr->msg ) );
0555   strcpy( message, "No Message" );
0556 
0557   sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
0558   fatal_int_service_status(priority, ptr->priority, err_msg );
0559 }
0560 
0561 int empty_message_queues(
0562   char *task_name
0563 )
0564 {
0565   int que;
0566   int i;
0567 
0568   printf( "%s Empty all Queues\n", task_name );
0569   for( que = RW_QUEUE; que < CLOSED; que++ ) {
0570     for(i=0; Test_q[que].count != 0; i++ )
0571       Read_msg_from_que( que,  Priority_Order[i] );
0572 
0573     Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
0574   }
0575   return 0;
0576 }
0577 
0578 /*
0579  * Returns the number of messages queued after the test on the
0580  * first queue.
0581  */
0582 int validate_mq_send_error_codes(void)
0583 {
0584   int             status;
0585   int             i;
0586   char           *str;
0587 
0588   Start_Test( "mq_send errors" );
0589 
0590   /*
0591    * EBADF - Write to a closed queue.
0592    */
0593 
0594   puts( "Init: mq_send - Closed message queue (EBADF)" );
0595   status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
0596   fatal_posix_service_status( status, -1, "mq_send error return status");
0597   fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
0598 
0599   /*
0600    * EBADF - Write to a read only  queue.
0601    */
0602 
0603   puts( "Init: mq_send - Read only message queue (EBADF)" );
0604   status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
0605   fatal_posix_service_status( status, -1, "mq_send error return status");
0606   fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
0607 
0608   /*
0609    * XXX - EINTR      Signal interrupted the call.
0610    *
0611   puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
0612   status = mq_send( Test_q, "", 0xffff, 0 );
0613   fatal_posix_service_status( status, -1, "mq_send error return status");
0614   fatal_posix_service_status( errno, E, "mq_send errno E");
0615    */
0616 
0617   /*
0618    * EINVAL priority is out of range.
0619    */
0620 
0621   puts( "Init: mq_send - Priority out of range (EINVAL)" );
0622   status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
0623   fatal_posix_service_status( status, -1, "mq_send error return status");
0624   fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
0625 
0626   /*
0627    *  EMSGSIZE - Message size larger than msg_len
0628    *             Validates that msgsize is stored correctly.
0629    */
0630 
0631   puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
0632   status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
0633   fatal_posix_service_status( status, -1, "mq_send error return status");
0634   fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
0635 
0636   i = fill_message_queues( "Init:" );
0637 
0638   /*
0639    * ENOSYS - send not supported
0640   puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
0641   status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
0642   fatal_posix_service_status( status, -1, "mq_send error return status");
0643   fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
0644 
0645   status = mq_close( n_mq1 );
0646   fatal_posix_service_status( status, 0, "mq_close message queue");
0647 
0648   status = mq_unlink( "read_only" );
0649   fatal_posix_service_status( status, 0, "mq_unlink message queue");
0650    */
0651 
0652   /*
0653    * EAGAIN - O_NONBLOCK and message queue is full.
0654    */
0655 
0656   puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
0657   str = Predefined_Msgs[i].msg;
0658   status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
0659   fatal_posix_service_status( status, -1, "mq_send error return status");
0660   fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
0661 
0662   return i-1;
0663 }
0664 
0665 void validate_mq_receive_error_codes(void)
0666 {
0667   int            status;
0668   char           message[100];
0669   unsigned int   priority;
0670 
0671   Start_Test( "mq_receive errors"  );
0672 
0673   /*
0674    * EBADF - Not A Valid Message Queue
0675    */
0676 
0677   puts( "Init: mq_receive - Unopened message queue (EBADF)" );
0678   status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
0679   fatal_posix_service_status( status, -1, "mq_ error return status");
0680   fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
0681 
0682   /*
0683    * EBADF - Queue not opened to read
0684    */
0685 
0686   puts( "Init: mq_receive - Write only queue (EBADF)" );
0687   status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
0688   fatal_posix_service_status( status, -1, "mq_ error return status");
0689   fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
0690 
0691   /*
0692    * EMSGSIZE - Size is less than the message size attribute
0693    */
0694 
0695   puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
0696   status = mq_receive(
0697     Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
0698   fatal_posix_service_status( status, -1, "mq_ error return status");
0699   fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
0700 
0701 
0702   /*
0703    * EAGAIN - O_NONBLOCK and Queue is empty
0704    */
0705   verify_queues_full( "Init:" );
0706   empty_message_queues( "Init:" );
0707 
0708   puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
0709   status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
0710   fatal_posix_service_status( status, -1, "mq_ error return status");
0711   fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
0712 
0713   /*
0714    * XXX - EINTR - Interrupted by a signal
0715    */
0716 
0717   /*
0718    * XXX - EBADMSG - a data corruption problem.
0719    */
0720 
0721   /*
0722    * XXX - ENOSYS - mq_receive not supported
0723    */
0724 }
0725 
0726 void verify_open_functionality(void)
0727 {
0728   mqd_t           n_mq;
0729   int             status;
0730 
0731   Start_Test( "mq_open functionality" );
0732 
0733   /*
0734    * Validate a second open returns the same message queue.
0735    */
0736 
0737   puts( "Init: mq_open - Open an existing mq ( same id )" );
0738   n_mq = mq_open( RD_NAME, 0 );
0739   rtems_test_assert( n_mq == Test_q[RD_QUEUE].mq );
0740   status = mq_close( n_mq );
0741   fatal_posix_service_status( status, 0, "mq_close");
0742 }
0743 
0744 void verify_unlink_functionality(void)
0745 {
0746   mqd_t           n_mq;
0747   int             status;
0748 
0749   Start_Test( "mq_unlink functionality" );
0750 
0751   /*
0752    * Unlink the message queue, then verify an open of the same name produces a
0753    * different message queue.
0754    */
0755 
0756   puts( "Init: Unlink and Open without closing SUCCESSFUL" );
0757   status = mq_unlink( DEFAULT_NAME );
0758   fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
0759 
0760   n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
0761   rtems_test_assert( n_mq != (-1) );
0762   rtems_test_assert( n_mq != Test_q[ DEFAULT_RW ].mq );
0763 
0764 
0765   status = mq_unlink( DEFAULT_NAME );
0766   fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
0767   status = mq_close( Test_q[ DEFAULT_RW ].mq );
0768   fatal_posix_service_status( status, 0, "mq_close message queue");
0769 
0770   Test_q[ DEFAULT_RW ].mq = n_mq;
0771 }
0772 
0773 void verify_close_functionality(void)
0774 {
0775   int i;
0776   int status;
0777   Start_Test( "Unlink and Close All Files"  );
0778   for (i=0; i<DEFAULT_RW; i++) {
0779 
0780     status = mq_unlink( Get_Queue_Name(i) );
0781     fatal_posix_service_status( status, 0, "mq_unlink message queue");
0782 
0783     status = mq_close( Test_q[i].mq );
0784     fatal_posix_service_status( status, 0, "mq_close message queue");
0785   }
0786 }
0787 
0788 
0789 void verify_timed_send_queue(
0790   int  que,
0791   int  is_blocking
0792 )
0793 {
0794   struct timespec timeout;
0795   struct timeval  tv1, tv2, tv3;
0796   struct timezone tz1, tz2;
0797   int              len;
0798   int              status;
0799   char            *msg;
0800 
0801   printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
0802   len = Predefined_Msgs[MAXMSG].size;
0803   msg = Predefined_Msgs[MAXMSG].msg;
0804 
0805   gettimeofday( &tv1, &tz1 );
0806   timeout.tv_sec  = tv1.tv_sec + 1;
0807   timeout.tv_nsec = tv1.tv_usec * 1000;
0808 
0809   status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
0810 
0811   gettimeofday( &tv2, &tz2 );
0812   tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
0813   tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
0814 
0815   if ( is_blocking ) { /* Don't verify the non-blocking queue */
0816     fatal_int_service_status( status, -1, "mq_timedsend status" );
0817     fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT" );
0818   }
0819 
0820   printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
0821 
0822   if ( que == DEFAULT_RW )
0823     Test_q[que].count++;
0824 }
0825 
0826 void verify_timed_send(void)
0827 {
0828   int              que;
0829 
0830   Start_Test( "mq_timedsend"  );
0831 
0832   for( que = RW_QUEUE; que < CLOSED; que++ ) {
0833     if ( que == BLOCKING )
0834       verify_timed_send_queue( que, 1 );
0835     else
0836       verify_timed_send_queue( que, 0 );
0837   }
0838 }
0839 
0840 void verify_timed_receive_queue(
0841   char *task_name,
0842   int   que,
0843   int   is_blocking
0844 )
0845 {
0846   char message[ 100 ];
0847   unsigned int priority;
0848   struct timespec tm;
0849   struct timeval  tv1, tv2, tv3;
0850   struct timezone tz1, tz2;
0851   int              status;
0852 
0853   printf(
0854     "Init: %s mq_timedreceive - on queue %s ",
0855     task_name,
0856     Test_q[que].name
0857   );
0858 
0859   gettimeofday( &tv1, &tz1 );
0860   tm.tv_sec  = tv1.tv_sec + 1;
0861   tm.tv_nsec = tv1.tv_usec * 1000;
0862 
0863   status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
0864 
0865   gettimeofday( &tv2, &tz2 );
0866   tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
0867   tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
0868 
0869   fatal_int_service_status( status, -1, "mq_timedreceive status");
0870   if ( is_blocking )
0871     fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
0872   printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
0873 
0874 }
0875 
0876 void verify_timed_receive(void)
0877 {
0878   int  que;
0879 
0880   Start_Test( "mq_timedreceive"  );
0881 
0882   for( que = RW_QUEUE; que < CLOSED; que++ ) {
0883     if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
0884       verify_timed_receive_queue( "Init:", que, 1 );
0885     else
0886       verify_timed_receive_queue( "Init:", que, 0 );
0887   }
0888 }
0889 
0890 #if (0)
0891 void verify_set_attr(void)
0892 {
0893   struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
0894   struct mq_attr attr;
0895   int            i;
0896   int            status;
0897 
0898   attr.mq_maxmsg  = 0;
0899   attr.mq_msgsize = 0;
0900 
0901   Start_Test( "mq_setattr"  );
0902 
0903   puts( "Init: set_attr all queues to blocking" );
0904   for(i=0; i<CLOSED; i++) {
0905     attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
0906     status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
0907     fatal_int_service_status( status, 0, "mq_setattr valid return status");
0908 
0909     Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
0910   }
0911 
0912   for( i = RW_QUEUE; i < CLOSED; i++ ) {
0913     verify_timed_receive_queue( "Init:", i, 1 );
0914   }
0915 
0916   for(i=0; i<CLOSED; i++) {
0917     attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
0918     status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
0919     fatal_int_service_status( status, 0, "mq_setattr valid return status");
0920 
0921     Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
0922   }
0923 }
0924 #endif
0925 
0926 void wait_for_signal(
0927   sigset_t     *waitset,
0928   int           sec,
0929   int           expect_signal
0930 )
0931 {
0932 #if defined(RTEMS_POSIX_API)
0933   siginfo_t         siginfo;
0934   int               status;
0935   struct timespec   timeout;
0936   int               signo;
0937 
0938   siginfo.si_code = -1;
0939   siginfo.si_signo = -1;
0940   siginfo.si_value.sival_int = -1;
0941 
0942   timeout.tv_sec = sec;
0943   timeout.tv_nsec = 0;
0944 
0945   status = sigemptyset( waitset );
0946   rtems_test_assert( !status );
0947 
0948   status = sigaddset( waitset, SIGUSR1 );
0949   rtems_test_assert( !status );
0950 
0951   printf( "waiting on any signal for %d seconds.\n", sec );
0952   signo = sigtimedwait( waitset, &siginfo, &timeout );
0953   if (expect_signal) {
0954     fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
0955   } else {
0956     fatal_int_service_status( signo, -1, "error return status");
0957     fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
0958   }
0959 #endif
0960 }
0961 
0962 void verify_notify(void)
0963 {
0964 #if defined(RTEMS_POSIX_API)
0965   struct sigevent event;
0966   int             status;
0967   timer_t         timer_id;
0968   sigset_t        set;
0969 
0970   Start_Test( "mq_notify"  );
0971 
0972   /* timer create */
0973   event.sigev_notify = SIGEV_SIGNAL;
0974   event.sigev_signo  = SIGUSR1;
0975   if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
0976     fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
0977 
0978   /* block the timer signal */
0979   sigemptyset( &set );
0980   sigaddset( &set, SIGUSR1 );
0981   pthread_sigmask( SIG_BLOCK, &set, NULL );
0982 
0983   /*
0984    * EBADF - Not A Valid Message Queue
0985    */
0986 
0987   puts( "Init: mq_notify - Unopened message queue (EBADF)" );
0988   status = mq_notify( Test_q[CLOSED].mq, NULL );
0989   fatal_posix_service_status( status, -1, "mq_ error return status");
0990   fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
0991 
0992   /*
0993    * Create ...
0994    */
0995 
0996   /*
0997    * XXX setup notification
0998    */
0999   printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
1000   status = mq_notify( Test_q[RW_QUEUE].mq, &event );
1001   fatal_posix_service_status( status, 0, "mq_notify valid status");
1002   wait_for_signal( &set, 3, 0 );
1003 
1004   /*
1005    * Send and verify signal occurs and registration is removed.
1006    */
1007 
1008   puts( "Init: Verify Signal when send" );
1009   Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
1010   wait_for_signal( &set, 3, 1 );
1011   Read_msg_from_que( RW_QUEUE, 0 );
1012 
1013   puts( "Init: Verify No Signal when send" );
1014   Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
1015   wait_for_signal( &set, 3, 0 );
1016   Read_msg_from_que( RW_QUEUE, 0 );
1017 
1018   /*
1019    * EBUSY - Already Registered
1020    */
1021 
1022   printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
1023   status = mq_notify( Test_q[RW_QUEUE].mq, &event );
1024   fatal_posix_service_status( status, 0, "mq_notify valid status");
1025   wait_for_signal( &set, 3, 0 );
1026 
1027   puts( "Init: mq_notify -  (EBUSY)" );
1028   status = mq_notify( Test_q[RW_QUEUE].mq, &event );
1029   fatal_posix_service_status( status, -1, "mq_notify error return status");
1030   fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
1031 
1032   /*
1033    * Verify NULL removes registration.
1034    */
1035 
1036   puts( "Init: mq_notify - Remove notification with null" );
1037   status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
1038   fatal_posix_service_status( status, 0, "mq_notify valid status");
1039 
1040   puts( "Init: Verify No Signal when send" );
1041   Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
1042   wait_for_signal( &set, 3, 0 );
1043   Read_msg_from_que( RW_QUEUE, 0 );
1044 #endif
1045 }
1046 
1047 void verify_with_threads(void)
1048 {
1049   int               status;
1050   pthread_t         id;
1051   Test_Message_t   *ptr;
1052 #if 0
1053   unsigned int      priority;
1054   char              message[100];
1055 #endif
1056 
1057 
1058 #if 0
1059   /*
1060    * Create a task then block until the task sends the message.
1061    * Task tests set attributes so one queue will have a thread
1062    * blocked while attributes are changed.
1063    */
1064 
1065   Start_Test( "multi-thread Task 4 Receive Test"  );
1066   status = pthread_create( &id, NULL, Task_4, NULL );
1067   rtems_test_assert( !status );
1068   puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
1069   status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
1070   fatal_int_service_status( status, -1, "mq_receive error return status");
1071   fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
1072   print_current_time( "Init: ", "" );
1073 #endif
1074   /*
1075    * Create a task then block until the task sends the message.
1076    * Task tests set attributes so one queue will have a thread
1077    * blocked while attributes are changed.
1078    */
1079 
1080   Start_Test( "multi-thread Task 1 Test"  );
1081   status = pthread_create( &id, NULL, Task_1, NULL );
1082   rtems_test_assert( !status );
1083   Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
1084   print_current_time( "Init: ", "" );
1085 
1086 #if 0
1087   /*
1088    * Fill the queue then create a task then block until the task receives a message.
1089    * Task tests set attributes so one queue will have a thread
1090    * blocked while attributes are changed.
1091    */
1092 
1093   Start_Test( "multi-thread Task 4 Send Test"  );
1094   fill_message_queues( "Init:" );
1095   status = pthread_create( &id, NULL, Task_4, NULL );
1096   rtems_test_assert( !status );
1097   puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
1098   status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
1099   fatal_posix_service_status( status, -1, "mq_send error return status");
1100   fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
1101   verify_queues_full( "Init:" );
1102   empty_message_queues( "Init:" );
1103 #endif
1104   /*
1105    * Create a task then block until the task reads a message.
1106    */
1107 
1108   Start_Test( "multi-thread Task 2 Test"  );
1109   fill_message_queues( "Init:" );
1110   status = pthread_create( &id, NULL, Task_2, NULL );
1111   rtems_test_assert( !status );
1112   Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
1113   print_current_time( "Init: ", "" );
1114   verify_queues_full( "Init:" );
1115   empty_message_queues( "Init:" );
1116 
1117   /*
1118    * Create a task then block until it deletes and closes all queues.
1119    *     EBADF - Queue unlinked and closed while blocked
1120    */
1121 
1122   Start_Test( "multi-thread Task 3 Test"  );
1123   fill_message_queues( "Init:" );
1124   status = pthread_create( &id, NULL, Task_3, NULL );
1125   rtems_test_assert( !status );
1126   puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
1127   ptr = &Predefined_Msgs[0];
1128   status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
1129   fatal_posix_service_status( status, -1, "mq_send error return status");
1130   fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
1131 
1132 }
1133 
1134 void validate_mq_setattr(void)
1135 {
1136   struct mq_attr  attr = { 0 };
1137   struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
1138   int             status;
1139   int            i;
1140 
1141   /*
1142    * EBADF - Get the attributes from a closed queue.
1143    */
1144 
1145   puts( "Task1:mq_setattr - unopened queue (EBADF)" );
1146   status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
1147   fatal_posix_service_status( status, -1, "mq_setattr error return status");
1148   fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF");
1149 
1150   /*
1151    * XXX - The following are not listed in the POSIX manual but
1152    *       may occur.
1153    */
1154 
1155   /*
1156    * EINVAL - NULL attributes
1157    */
1158 
1159   puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
1160   status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
1161   fatal_posix_service_status( status, -1, "mq_setattr error return status");
1162   fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL");
1163 
1164   /*
1165    * Verify change queues to blocking, by verifying all queues block
1166    * for a timed receive.
1167    */
1168 
1169   puts( "Init: set_attr all queues to blocking" );
1170   for(i=0; i<CLOSED; i++) {
1171     attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
1172     status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
1173     fatal_int_service_status( status, 0, "mq_setattr valid return status");
1174     Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
1175   }
1176   for( i = RW_QUEUE; i < CLOSED; i++ ) {
1177     verify_timed_receive_queue( "Init:", i, 1 );
1178   }
1179 
1180   /*
1181    * Restore restore all queues to their old attribute.
1182    */
1183 
1184   for(i=0; i<CLOSED; i++) {
1185     status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
1186     fatal_int_service_status( status, 0, "mq_setattr valid return status");
1187     Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
1188   }
1189 }
1190 
1191 void verify_timedout_mq_timedreceive(
1192   char *task_name,
1193   int   que,
1194   int   is_blocking
1195 )
1196 {
1197   char             message[ 100 ];
1198   struct timespec  tm;
1199   struct timeval   tv1, tv2, tv3;
1200   struct timezone  tz1, tz2;
1201   int              status;
1202 
1203   printf(
1204     "Init: %s verify_timedout_mq_timedreceive - on queue %s ",
1205     task_name,
1206     Test_q[que].name
1207   );
1208 
1209   gettimeofday( &tv1, &tz1 );
1210   tm.tv_sec  = tv1.tv_sec - 1;
1211   tm.tv_nsec = tv1.tv_usec * 1000;
1212 
1213   status = mq_timedreceive( Test_q[ que ].mq, message, 100, NULL, &tm );
1214 
1215   gettimeofday( &tv2, &tz2 );
1216   tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
1217   tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
1218 
1219   fatal_int_service_status( status, -1, "mq_timedreceive status");
1220 
1221 /* FIXME: This is wrong. */
1222   printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
1223 }
1224 
1225 void verify_mq_receive(void)
1226 {
1227   int  que;
1228 
1229   Start_Test( "mq_timedout_receive"  );
1230 
1231   for( que = RW_QUEUE; que < CLOSED; que++ ) {
1232     if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
1233       break;
1234     else
1235       verify_timedout_mq_timedreceive( "Init:", que, 0 );
1236   }
1237 }
1238 
1239 void verify_timedout_mq_timedsend(
1240   int  que,
1241   int  is_blocking
1242 )
1243 {
1244   struct timespec timeout;
1245   struct timeval  tv1, tv2, tv3;
1246   struct timezone tz1, tz2;
1247   int              len;
1248   char            *msg;
1249 
1250   printf( "Init: verify_timedout_mq_timedsend - on queue %s ", Test_q[que].name);
1251   len = Predefined_Msgs[MAXMSG].size;
1252   msg = Predefined_Msgs[MAXMSG].msg;
1253 
1254   gettimeofday( &tv1, &tz1 );
1255   timeout.tv_sec  = tv1.tv_sec - 1;
1256   timeout.tv_nsec = tv1.tv_usec * 1000;
1257 
1258   (void) mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
1259 
1260   gettimeofday( &tv2, &tz2 );
1261   tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
1262   tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
1263 
1264   printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
1265 
1266   if ( que == DEFAULT_RW )
1267     Test_q[que].count++;
1268 }
1269 
1270 void verify_mq_send(void)
1271 {
1272   int              que;
1273 
1274   Start_Test( "verify_timedout_mq_timedsend"  );
1275 
1276   for( que = RW_QUEUE; que < CLOSED; que++ ) {
1277     if ( que == BLOCKING )
1278       verify_timedout_mq_timedsend( que, 1 );
1279     else
1280       verify_timedout_mq_timedsend( que, 0 );
1281   }
1282 }
1283 
1284 static void *receive_maxmsg_plus_one( void *arg )
1285 {
1286   mqd_t                 mq;
1287   const Test_Message_t *m;
1288   int                   i;
1289 
1290   mq = Test_q[ BLOCKING ].mq;
1291   m = &Predefined_Msgs[ 0 ];
1292 
1293   for ( i = 0; i < MAXMSG + 1; ++i ) {
1294     Test_Message_t a;
1295     unsigned       prio;
1296     ssize_t        n;
1297 
1298     n = mq_receive( mq, &a.msg[0], sizeof(a.msg), &prio);
1299     rtems_test_assert( n == m->size );
1300     rtems_test_assert( prio == m->priority );
1301     rtems_test_assert( memcmp( &a.msg[0], &m->msg[0], (size_t) n ) == 0 );
1302   }
1303 
1304   return arg;
1305 }
1306 
1307 static void verify_blocking_mq_timedsend( void )
1308 {
1309   mqd_t                 mq;
1310   const Test_Message_t *m;
1311   int                   status;
1312   struct timespec       timeout;
1313   pthread_t             thread;
1314   void                 *exit_value;
1315   rtems_status_code     sc;
1316 
1317   Start_Test( "verify_blocking_mq_timedsend"  );
1318 
1319   mq = Test_q[ BLOCKING ].mq;
1320   m = &Predefined_Msgs[ 0 ];
1321 
1322   /*
1323    * Create and suspend the receive thread early so that we don't overwrite the
1324    * ETIMEDOUT in executing->Wait.return_code.  This verifies the succesful
1325    * mq_timedreceive() later.
1326    */
1327 
1328   status = pthread_create( &thread, NULL, receive_maxmsg_plus_one, &thread );
1329   fatal_posix_service_status( status, 0, "pthread_create" );
1330 
1331   sc = rtems_task_suspend( thread );
1332   fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_suspend" );
1333 
1334   do {
1335     status = clock_gettime( CLOCK_REALTIME, &timeout );
1336     fatal_posix_service_status( status, 0, "clock_gettime" );
1337     ++timeout.tv_sec;
1338 
1339     status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
1340   } while ( status == 0 );
1341 
1342   fatal_posix_service_status_errno( status, ETIMEDOUT, "mq_timedsend");
1343 
1344   sc = rtems_task_resume( thread );
1345   fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_resume" );
1346 
1347   status = clock_gettime( CLOCK_REALTIME, &timeout );
1348   fatal_posix_service_status( status, 0, "clock_gettime" );
1349   ++timeout.tv_sec;
1350 
1351   status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
1352   fatal_posix_service_status( status, 0, "mq_timedsend" );
1353 
1354   exit_value = NULL;
1355   status = pthread_join( thread, &exit_value );
1356   fatal_posix_service_status( status, 0, "pthread_join" );
1357   rtems_test_assert( exit_value == &thread );
1358 }
1359 
1360 void *POSIX_Init(
1361   void *argument
1362 )
1363 {
1364   TEST_BEGIN();
1365 
1366   validate_mq_open_error_codes( );
1367   open_test_queues();
1368   verify_blocking_mq_timedsend();
1369   validate_mq_unlink_error_codes();
1370   validate_mq_close_error_codes();
1371   verify_unlink_functionality();
1372   validate_mq_setattr( );
1373   validate_mq_send_error_codes();
1374   validate_mq_getattr_error_codes();
1375   verify_timed_send();
1376   validate_mq_receive_error_codes();
1377   verify_timed_receive();
1378   verify_open_functionality();
1379   verify_notify();
1380   verify_with_threads();
1381   verify_mq_receive();
1382   verify_mq_send();
1383 
1384   TEST_END();
1385   rtems_test_exit( 0 );
1386 
1387   return NULL; /* just so the compiler thinks we returned something */
1388 }
1389 
1390 
1391 void *Task_1 (
1392   void *argument
1393 )
1394 {
1395   /* Block Waiting for a message */
1396 
1397   print_current_time( "Task_1: ", "" );
1398 
1399   Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
1400 
1401   puts( "Task_1: pthread_exit" );
1402   pthread_exit( NULL );
1403 
1404   /* switch to Init */
1405 
1406   rtems_test_assert( 0 );
1407   return NULL; /* just so the compiler thinks we returned something */
1408 }
1409 
1410 void *Task_2(
1411   void *argument
1412 )
1413 {
1414   print_current_time( "Task_2: ", "" );
1415 
1416 
1417   /* Block waiting to send a message */
1418 
1419   verify_queues_full( "Task_2:" );
1420   Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
1421 
1422   puts( "Task_2: pthread_exit" );
1423   pthread_exit( NULL );
1424 
1425      /* switch to Init */
1426 
1427   return NULL; /* just so the compiler thinks we returned something */
1428 }
1429 
1430 void *Task_3 (
1431   void *argument
1432 )
1433 {
1434 
1435   print_current_time( "Task_3: ", "" );
1436 
1437   /*
1438    * close and unlink all queues.
1439    */
1440 
1441   verify_close_functionality();
1442   puts( "Task_3: pthread_exit" );
1443   pthread_exit( NULL );
1444 
1445      /* switch to Init */
1446 
1447   return NULL; /* just so the compiler thinks we returned something */
1448 
1449 }
1450 
1451 void *Task_4 (
1452   void *argument
1453 )
1454 {
1455   struct mq_attr  attr;
1456   int             status;
1457   int             count;
1458 
1459   print_current_time( "Task_4: ", "" );
1460 
1461   /*
1462    * Set the count to the number of messages in the queue.
1463    */
1464 
1465   status = mq_getattr( Test_q[BLOCKING].mq, &attr );
1466   fatal_posix_service_status( status, 0, "mq_getattr valid return status");
1467   count = attr.mq_curmsgs;
1468 
1469   puts("Task_4: Set queue to non-blocking");
1470   attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
1471   status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1472   fatal_int_service_status( status, 0, "mq_setattr valid return status");
1473   Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1474 
1475   puts("Task_4: Return queue to blocking");
1476   attr.mq_flags =  Test_q[BLOCKING].oflag;
1477   status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1478   fatal_int_service_status( status, 0, "mq_setattr valid return status");
1479   Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1480 
1481   puts( "Task_4: pthread_exit" );
1482   pthread_exit( NULL );
1483 
1484      /* switch to Init */
1485 
1486   return NULL; /* just so the compiler thinks we returned something */
1487 
1488 }
1489 
1490 void *Task_5 (
1491   void *argument
1492 )
1493 {
1494 
1495   print_current_time( "Task_5: ", "" );
1496 
1497   puts( "Task_5: pthread_exit" );
1498   pthread_exit( NULL );
1499 
1500      /* switch to Init */
1501 
1502   return NULL; /* just so the compiler thinks we returned something */
1503 
1504 }