source: rtems/testsuites/psxtests/psxmsgq01/init.c

Last change on this file was 6b2c5b5d, checked in by Chris Johns <chrisj@…>, on 06/20/22 at 02:04:43

testsuite: Fix gcc 12 warnings

  • Property mode set to 100644
File size: 41.4 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 *  COPYRIGHT (c) 1989-2012.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#define CONFIGURE_INIT
34#include "system.h"
35#include <sched.h>
36#include <fcntl.h>
37#include <time.h>
38#include <tmacros.h>
39#include <signal.h>   /* signal facilities */
40#include "test_support.h"
41
42const char rtems_test_name[] = "PSXMSGQ 1";
43
44/* forward declarations to avoid warnings */
45void Start_Test(char *description);
46void Validate_attributes(mqd_t mq, int oflag, int msg_count);
47char *Build_Queue_Name(int i);
48void open_test_queues(void);
49void validate_mq_open_error_codes(void);
50void validate_mq_unlink_error_codes(void);
51void validate_mq_close_error_codes(void);
52void validate_mq_getattr_error_codes(void);
53void Send_msg_to_que(int que, int msg);
54void Show_send_msg_to_que(char *task_name, int que, int msg);
55void verify_queues_full(char *task_name);
56void verify_queues_empty(char *task_name);
57int empty_message_queues(char *task_name);
58int fill_message_queues(char *task_name);
59void Read_msg_from_que(int que, int msg);
60int validate_mq_send_error_codes(void);
61void validate_mq_receive_error_codes(void);
62void verify_open_functionality(void);
63void verify_unlink_functionality(void);
64void verify_close_functionality(void);
65void verify_timed_send_queue(int que, int is_blocking);
66void verify_timed_send(void);
67void verify_timed_receive_queue(char *task_name, int que, int is_blocking);
68void verify_timed_receive(void);
69void wait_for_signal(sigset_t *waitset, int sec, int expect_signal);
70void verify_notify(void);
71void verify_with_threads(void);
72void verify_timedout_mq_timedreceive(char *task_name, int que, int is_blocking);
73void verify_timedout_mq_timedsend(int que, int is_blocking);
74void verify_timed_receive(void);
75void validate_mq_setattr(void);
76void verify_timedout_mq_timedreceive(
77  char *task_name, int que, int is_blocking);
78void verify_mq_receive(void);
79void verify_timedout_mq_timedsend(int que, int is_blocking);
80void verify_mq_send(void);
81void verify_timed_receive(void);
82
83typedef struct {
84  char         msg[ 50 ];
85  int          size;
86  unsigned int priority;
87} Test_Message_t;
88
89Test_Message_t Predefined_Msgs[MAXMSG+1];
90Test_Message_t Predefined_Msgs[MAXMSG+1] = {
91  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
92  { "",           1, 1             },  /* NULL  Message      low  */
93  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */
94  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
95  { "1",          2, 0             },  /* Cause Overflow Behavior */
96};
97int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
98
99
100typedef struct {
101  mqd_t              mq;
102  Test_Queue_Types   index;
103  char              *name;
104  int                oflag;
105  int                maxmsg;
106  int                msgsize;
107  int                count;
108} Test_queue_type;
109
110Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES + 1 ] =
111{
112  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
113  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
114  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
115  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
116  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
117  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
118  { 0, 6, "Qblock",   (           O_RDWR )               , MAXMSG, MSGSIZE, 0 },
119};
120
121#define RW_NAME             Test_q[ RW_QUEUE ].name
122#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
123#define RD_NAME             Test_q[ RD_QUEUE ].name
124#define WR_NAME             Test_q[ WR_QUEUE ].name
125#define BLOCKING_NAME       Test_q[ BLOCKING ].name
126#define CLOSED_NAME         Test_q[ CLOSED ].name
127
128#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
129#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
130#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
131#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
132#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
133#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
134
135/*
136 * Outputs a header at each test section.
137 */
138void Start_Test(
139  char *description
140)
141{
142  printf( "_______________%s\n", description );
143}
144
145
146void Validate_attributes(
147  mqd_t  mq,
148  int    oflag,
149  int    msg_count
150)
151{
152  int             status;
153  struct mq_attr  attr;
154
155  status = mq_getattr( mq, &attr );
156  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
157
158  if ( mq != Test_q[ DEFAULT_RW ].mq ){
159    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
160    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
161  }
162
163  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
164  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
165}
166
167#define Get_Queue_Name( i )  Test_q[i].name
168char *Build_Queue_Name(int i)
169{
170  static char Queue_Name[PATH_MAX + 2];
171
172  sprintf(Queue_Name,"mq%d", i+1 );
173  return Queue_Name;
174}
175
176void open_test_queues(void)
177{
178  struct mq_attr   attr;
179  int              status;
180  Test_queue_type *tq;
181  int              que;
182
183  attr.mq_maxmsg  = MAXMSG;
184  attr.mq_msgsize = MSGSIZE;
185
186  puts( "Init: Open Test Queues" );
187
188  for( que = 0; que < NUMBER_OF_TEST_QUEUES+1; que++ ) {
189
190    tq = &Test_q[ que ];
191    if ( que == DEFAULT_RW)
192      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
193    else
194      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
195
196    rtems_test_assert( Test_q[que].mq != (-1) );
197  }
198
199  status = mq_close( Test_q[NUMBER_OF_TEST_QUEUES].mq );
200  fatal_posix_service_status( status, 0, "mq_close duplicate message queue");
201  status = mq_close( Test_q[CLOSED].mq );
202  fatal_posix_service_status( status, 0, "mq_close message queue");
203  status = mq_unlink( CLOSED_NAME );
204  fatal_posix_service_status( status, 0, "mq_unlink message queue");
205}
206
207/*
208 * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues
209 * opened but closes the rest.
210 */
211
212void validate_mq_open_error_codes(void)
213{
214  int             i;
215  mqd_t           n_mq2;
216  struct mq_attr  attr;
217  int             status;
218  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1];
219
220  attr.mq_maxmsg  = MAXMSG;
221  attr.mq_msgsize = MSGSIZE;
222
223  Start_Test( "mq_open errors" );
224
225  /*
226   * XXX EINVAL - inappropriate name was given for the message queue
227   */
228
229  /*
230   * EINVAL - Create with negative maxmsg.
231   */
232
233  attr.mq_maxmsg = -1;
234  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
235  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
236  fatal_posix_mqd( n_mq2, "mq_open error return status" );
237  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
238  attr.mq_maxmsg  = MAXMSG;
239
240  /*
241   * EINVAL - Create withnegative msgsize.
242   */
243
244  attr.mq_msgsize = -1;
245  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
246  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
247  fatal_posix_mqd( n_mq2, "mq_open error return status" );
248  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
249  attr.mq_msgsize = MSGSIZE;
250
251  /*
252   * ENOENT - Open a non-created file.
253   */
254
255  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
256  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
257  fatal_posix_mqd( n_mq2, "mq_open error return status" );
258  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
259
260  /*
261   * XXX EINTR  - call was interrupted by a signal
262   */
263
264  /*
265   * ENAMETOOLONG - Give a name greater than PATH_MAX.
266   */
267
268  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
269  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
270  fatal_posix_mqd( n_mq2, "mq_open error return status" );
271  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
272
273  /*
274   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
275   *       Per implementation not possible.
276   */
277
278  /*
279   * EEXIST - Create an existing queue.
280   */
281
282  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
283  open_mq[0] = mq_open(
284    Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
285  rtems_test_assert( open_mq[0] != (-1) );
286
287  n_mq2 = mq_open(
288    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
289  fatal_posix_mqd( n_mq2, "mq_open error return status" );
290  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
291
292  status = mq_unlink( Build_Queue_Name(0) );
293  fatal_posix_service_status( status, 0, "mq_unlink message queue");
294
295  status = mq_close( open_mq[0]);
296  fatal_posix_service_status( status, 0, "mq_close message queue");
297
298  /*
299   * Open maximum number of message queues
300   */
301
302  puts( "Init: mq_open - SUCCESSFUL" );
303  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
304    open_mq[i] = mq_open(
305      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
306    rtems_test_assert( open_mq[i] != (-1) );
307    rtems_test_assert( open_mq[i] );
308    /*XXX - Isn't there a more general check */
309/* JRS     printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
310  }
311
312  /*
313   * XXX EACCES - permission to create is denied.
314   */
315
316  /*
317   * XXX EACCES - queue exists permissions specified by o_flag are denied.
318   */
319
320  /*
321   * XXX EMFILE  - Too many message queues in use by the process
322   */
323
324  /*
325   * ENFILE -  Too many message queues open in the system
326   */
327
328  puts( "Init: mq_open - system is out of resources (ENFILE)" );
329  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
330  fatal_posix_mqd( n_mq2, "mq_open error return status" );
331  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
332
333  /*
334   * Unlink and Close all queues.
335   */
336
337  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
338  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
339
340    status = mq_close( open_mq[i]);
341    fatal_posix_service_status( status, 0, "mq_close message queue");
342
343    status = mq_unlink( Build_Queue_Name(i) );
344    if ( status == -1 )
345      perror( "mq_unlink" );
346    fatal_posix_service_status( status, 0, "mq_unlink message queue");
347    /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
348  }
349}
350
351void validate_mq_unlink_error_codes(void)
352{
353  int             status;
354
355  Start_Test( "mq_unlink errors" );
356
357  /*
358   * XXX - EACCES Permission Denied
359   */
360
361  /*
362   * ENAMETOOLONG - Give a name greater than PATH_MAX.
363   */
364
365  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
366  status = mq_unlink( Get_Too_Long_Name() );
367  fatal_posix_service_status( status, -1, "mq_unlink error return status");
368  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
369
370  /*
371   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
372   *       Per implementation not possible.
373   */
374
375  /*
376   *  ENOENT - Unlink an unopened queue
377   */
378
379  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
380  status = mq_unlink( CLOSED_NAME );
381  fatal_posix_service_status( status, -1, "mq_unlink error return status");
382  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
383
384  /*
385   * XXX - The following were not listed in the POSIX document as
386   *       possible errors.  Under other commands the EINVAL is
387   *       given for these conditions.
388   */
389
390  /*
391   *  EINVAL - Unlink a queue with no name
392   */
393
394  puts( "Init: mq_unlink (NULL) - EINVAL" );
395  status = mq_unlink( NULL );
396  fatal_posix_service_status( status, -1, "mq_unlink error return status");
397  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
398
399  /*
400   *  ENOENT - Unlink a queue with a zero length name
401   */
402
403  puts( "Init: mq_unlink (\"\") - ENOENT" );
404  status = mq_unlink( "" );
405  fatal_posix_service_status( status, -1, "mq_unlink error return status");
406  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno value");
407}
408
409void validate_mq_close_error_codes(void)
410{
411  int             status;
412
413  Start_Test( "mq_close errors" );
414
415  /*
416   * EBADF - Close a queue that is not open.
417   */
418
419  puts( "Init: mq_close - unopened queue (EBADF)" );
420  status = mq_close( Test_q[CLOSED].mq );
421  fatal_posix_service_status( status, -1, "mq_close error return status");
422  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
423}
424
425
426void validate_mq_getattr_error_codes(void)
427{
428  struct mq_attr  attr;
429  int             status;
430
431  Start_Test( "mq_getattr errors" );
432
433  /*
434   * EBADF - Get the attributes from a closed queue.
435   */
436
437  puts( "Init: mq_getattr - unopened queue (EBADF)" );
438  status = mq_getattr( Test_q[CLOSED].mq, &attr );
439  fatal_posix_service_status( status, -1, "mq_close error return status");
440  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
441
442  /*
443   * XXX - The following are not listed in the POSIX manual but
444   *       may occur.
445   */
446
447  /*
448   * EINVAL - NULL attributes
449   */
450
451  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
452  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
453  fatal_posix_service_status( status, -1, "mq_close error return status");
454  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL");
455
456}
457
458
459void Send_msg_to_que(
460  int que,
461  int msg
462)
463{
464  Test_Message_t *ptr = &Predefined_Msgs[msg];
465  int             status;
466
467  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
468  fatal_posix_service_status( status, 0, "mq_send valid return status");
469  Test_q[que].count++;
470}
471
472void Show_send_msg_to_que(
473  char *task_name,
474  int   que,
475  int   msg
476)
477{
478  Test_Message_t *ptr = &Predefined_Msgs[msg];
479  printf( "%s mq_send -  to %s msg: %s priority %d\n",
480    task_name, Test_q[que].name, ptr->msg, ptr->priority);
481  Send_msg_to_que( que, msg );
482}
483
484void verify_queues_full(
485  char *task_name
486)
487{
488  int          que;
489
490  /*
491   * Validate that the queues are full.
492   */
493
494  printf( "%s Verify Queues are full\n", task_name );
495  for( que = RW_QUEUE; que < CLOSED; que++ )
496    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
497
498}
499void verify_queues_empty(
500  char *task_name
501)
502{
503  int             que;
504
505  printf( "%s Verify Queues are empty\n", task_name );
506  for( que = RW_QUEUE; que < CLOSED; que++ )
507    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
508}
509
510int fill_message_queues(
511  char *task_name
512)
513{
514  int             msg;
515  int             que;
516
517
518  verify_queues_empty( task_name );
519
520  /*
521   * Fill Queue with predefined messages.
522   */
523
524  printf( "%s Fill Queues with messages\n", task_name );
525  for(msg=0; msg<MAXMSG; msg++){
526    for( que = RW_QUEUE; que < CLOSED; que++ ) {
527      Send_msg_to_que( que, msg );
528    }
529  }
530
531  verify_queues_full( "Init:" );
532  return msg;
533}
534
535
536void Read_msg_from_que(
537  int que,
538  int msg
539)
540{
541  unsigned int    priority;
542  Test_Message_t *ptr;
543  int             status;
544  char            message[100];
545  char            err_msg[100];
546
547  ptr = &Predefined_Msgs[msg];
548  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
549  Test_q[que].count--;
550
551  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
552  fatal_int_service_status( status, ptr->size, err_msg );
553
554  rtems_test_assert( !strcmp( message, ptr->msg ) );
555  strcpy( message, "No Message" );
556
557  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
558  fatal_int_service_status(priority, ptr->priority, err_msg );
559}
560
561int empty_message_queues(
562  char *task_name
563)
564{
565  int que;
566  int i;
567
568  printf( "%s Empty all Queues\n", task_name );
569  for( que = RW_QUEUE; que < CLOSED; que++ ) {
570    for(i=0; Test_q[que].count != 0; i++ )
571      Read_msg_from_que( que,  Priority_Order[i] );
572
573    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
574  }
575  return 0;
576}
577
578/*
579 * Returns the number of messages queued after the test on the
580 * first queue.
581 */
582int validate_mq_send_error_codes(void)
583{
584  int             status;
585  int             i;
586  char           *str;
587
588  Start_Test( "mq_send errors" );
589
590  /*
591   * EBADF - Write to a closed queue.
592   */
593
594  puts( "Init: mq_send - Closed message queue (EBADF)" );
595  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
596  fatal_posix_service_status( status, -1, "mq_send error return status");
597  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
598
599  /*
600   * EBADF - Write to a read only  queue.
601   */
602
603  puts( "Init: mq_send - Read only message queue (EBADF)" );
604  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
605  fatal_posix_service_status( status, -1, "mq_send error return status");
606  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
607
608  /*
609   * XXX - EINTR      Signal interrupted the call.
610   *
611  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
612  status = mq_send( Test_q, "", 0xffff, 0 );
613  fatal_posix_service_status( status, -1, "mq_send error return status");
614  fatal_posix_service_status( errno, E, "mq_send errno E");
615   */
616
617  /*
618   * EINVAL priority is out of range.
619   */
620
621  puts( "Init: mq_send - Priority out of range (EINVAL)" );
622  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
623  fatal_posix_service_status( status, -1, "mq_send error return status");
624  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
625
626  /*
627   *  EMSGSIZE - Message size larger than msg_len
628   *             Validates that msgsize is stored correctly.
629   */
630
631  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
632  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
633  fatal_posix_service_status( status, -1, "mq_send error return status");
634  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
635
636  i = fill_message_queues( "Init:" );
637
638  /*
639   * ENOSYS - send not supported
640  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
641  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
642  fatal_posix_service_status( status, -1, "mq_send error return status");
643  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
644
645  status = mq_close( n_mq1 );
646  fatal_posix_service_status( status, 0, "mq_close message queue");
647
648  status = mq_unlink( "read_only" );
649  fatal_posix_service_status( status, 0, "mq_unlink message queue");
650   */
651
652  /*
653   * EAGAIN - O_NONBLOCK and message queue is full.
654   */
655
656  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
657  str = Predefined_Msgs[i].msg;
658  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
659  fatal_posix_service_status( status, -1, "mq_send error return status");
660  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
661
662  return i-1;
663}
664
665void validate_mq_receive_error_codes(void)
666{
667  int            status;
668  char           message[100];
669  unsigned int   priority;
670
671  Start_Test( "mq_receive errors"  );
672
673  /*
674   * EBADF - Not A Valid Message Queue
675   */
676
677  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
678  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
679  fatal_posix_service_status( status, -1, "mq_ error return status");
680  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
681
682  /*
683   * EBADF - Queue not opened to read
684   */
685
686  puts( "Init: mq_receive - Write only queue (EBADF)" );
687  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
688  fatal_posix_service_status( status, -1, "mq_ error return status");
689  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
690
691  /*
692   * EMSGSIZE - Size is less than the message size attribute
693   */
694
695  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
696  status = mq_receive(
697    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
698  fatal_posix_service_status( status, -1, "mq_ error return status");
699  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
700
701
702  /*
703   * EAGAIN - O_NONBLOCK and Queue is empty
704   */
705  verify_queues_full( "Init:" );
706  empty_message_queues( "Init:" );
707
708  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
709  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
710  fatal_posix_service_status( status, -1, "mq_ error return status");
711  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
712
713  /*
714   * XXX - EINTR - Interrupted by a signal
715   */
716
717  /*
718   * XXX - EBADMSG - a data corruption problem.
719   */
720
721  /*
722   * XXX - ENOSYS - mq_receive not supported
723   */
724}
725
726void verify_open_functionality(void)
727{
728  mqd_t           n_mq;
729  int             status;
730
731  Start_Test( "mq_open functionality" );
732
733  /*
734   * Validate a second open returns the same message queue.
735   */
736
737  puts( "Init: mq_open - Open an existing mq ( same id )" );
738  n_mq = mq_open( RD_NAME, 0 );
739  rtems_test_assert( n_mq == Test_q[RD_QUEUE].mq );
740  status = mq_close( n_mq );
741  fatal_posix_service_status( status, 0, "mq_close");
742}
743
744void verify_unlink_functionality(void)
745{
746  mqd_t           n_mq;
747  int             status;
748
749  Start_Test( "mq_unlink functionality" );
750
751  /*
752   * Unlink the message queue, then verify an open of the same name produces a
753   * different message queue.
754   */
755
756  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
757  status = mq_unlink( DEFAULT_NAME );
758  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
759
760  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
761  rtems_test_assert( n_mq != (-1) );
762  rtems_test_assert( n_mq != Test_q[ DEFAULT_RW ].mq );
763
764
765  status = mq_unlink( DEFAULT_NAME );
766  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
767  status = mq_close( Test_q[ DEFAULT_RW ].mq );
768  fatal_posix_service_status( status, 0, "mq_close message queue");
769
770  Test_q[ DEFAULT_RW ].mq = n_mq;
771}
772
773void verify_close_functionality(void)
774{
775  int i;
776  int status;
777  Start_Test( "Unlink and Close All Files"  );
778  for (i=0; i<DEFAULT_RW; i++) {
779
780    status = mq_unlink( Get_Queue_Name(i) );
781    fatal_posix_service_status( status, 0, "mq_unlink message queue");
782
783    status = mq_close( Test_q[i].mq );
784    fatal_posix_service_status( status, 0, "mq_close message queue");
785  }
786}
787
788
789void verify_timed_send_queue(
790  int  que,
791  int  is_blocking
792)
793{
794  struct timespec timeout;
795  struct timeval  tv1, tv2, tv3;
796  struct timezone tz1, tz2;
797  int              len;
798  int              status;
799  char            *msg;
800
801  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
802  len = Predefined_Msgs[MAXMSG].size;
803  msg = Predefined_Msgs[MAXMSG].msg;
804
805  gettimeofday( &tv1, &tz1 );
806  timeout.tv_sec  = tv1.tv_sec + 1;
807  timeout.tv_nsec = tv1.tv_usec * 1000;
808
809  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
810
811  gettimeofday( &tv2, &tz2 );
812  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
813  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
814
815  if ( is_blocking ) { /* Don't verify the non-blocking queue */
816    fatal_int_service_status( status, -1, "mq_timedsend status" );
817    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT" );
818  }
819
820  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
821
822  if ( que == DEFAULT_RW )
823    Test_q[que].count++;
824}
825
826void verify_timed_send(void)
827{
828  int              que;
829
830  Start_Test( "mq_timedsend"  );
831
832  for( que = RW_QUEUE; que < CLOSED; que++ ) {
833    if ( que == BLOCKING )
834      verify_timed_send_queue( que, 1 );
835    else
836      verify_timed_send_queue( que, 0 );
837  }
838}
839
840void verify_timed_receive_queue(
841  char *task_name,
842  int   que,
843  int   is_blocking
844)
845{
846  char message[ 100 ];
847  unsigned int priority;
848  struct timespec tm;
849  struct timeval  tv1, tv2, tv3;
850  struct timezone tz1, tz2;
851  int              status;
852
853  printf(
854    "Init: %s mq_timedreceive - on queue %s ",
855    task_name,
856    Test_q[que].name
857  );
858
859  gettimeofday( &tv1, &tz1 );
860  tm.tv_sec  = tv1.tv_sec + 1;
861  tm.tv_nsec = tv1.tv_usec * 1000;
862
863  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
864
865  gettimeofday( &tv2, &tz2 );
866  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
867  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
868
869  fatal_int_service_status( status, -1, "mq_timedreceive status");
870  if ( is_blocking )
871    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
872  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
873
874}
875
876void verify_timed_receive(void)
877{
878  int  que;
879
880  Start_Test( "mq_timedreceive"  );
881
882  for( que = RW_QUEUE; que < CLOSED; que++ ) {
883    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
884      verify_timed_receive_queue( "Init:", que, 1 );
885    else
886      verify_timed_receive_queue( "Init:", que, 0 );
887  }
888}
889
890#if (0)
891void verify_set_attr(void)
892{
893  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
894  struct mq_attr attr;
895  int            i;
896  int            status;
897
898  attr.mq_maxmsg  = 0;
899  attr.mq_msgsize = 0;
900
901  Start_Test( "mq_setattr"  );
902
903  puts( "Init: set_attr all queues to blocking" );
904  for(i=0; i<CLOSED; i++) {
905    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
906    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
907    fatal_int_service_status( status, 0, "mq_setattr valid return status");
908
909    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
910  }
911
912  for( i = RW_QUEUE; i < CLOSED; i++ ) {
913    verify_timed_receive_queue( "Init:", i, 1 );
914  }
915
916  for(i=0; i<CLOSED; i++) {
917    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
918    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
919    fatal_int_service_status( status, 0, "mq_setattr valid return status");
920
921    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
922  }
923}
924#endif
925
926void wait_for_signal(
927  sigset_t     *waitset,
928  int           sec,
929  int           expect_signal
930)
931{
932#if defined(RTEMS_POSIX_API)
933  siginfo_t         siginfo;
934  int               status;
935  struct timespec   timeout;
936  int               signo;
937
938  siginfo.si_code = -1;
939  siginfo.si_signo = -1;
940  siginfo.si_value.sival_int = -1;
941
942  timeout.tv_sec = sec;
943  timeout.tv_nsec = 0;
944
945  status = sigemptyset( waitset );
946  rtems_test_assert( !status );
947
948  status = sigaddset( waitset, SIGUSR1 );
949  rtems_test_assert( !status );
950
951  printf( "waiting on any signal for %d seconds.\n", sec );
952  signo = sigtimedwait( waitset, &siginfo, &timeout );
953  if (expect_signal) {
954    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
955  } else {
956    fatal_int_service_status( signo, -1, "error return status");
957    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
958  }
959#endif
960}
961
962void verify_notify(void)
963{
964#if defined(RTEMS_POSIX_API)
965  struct sigevent event;
966  int             status;
967  timer_t         timer_id;
968  sigset_t        set;
969
970  Start_Test( "mq_notify"  );
971
972  /* timer create */
973  event.sigev_notify = SIGEV_SIGNAL;
974  event.sigev_signo  = SIGUSR1;
975  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
976    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
977
978  /* block the timer signal */
979  sigemptyset( &set );
980  sigaddset( &set, SIGUSR1 );
981  pthread_sigmask( SIG_BLOCK, &set, NULL );
982
983  /*
984   * EBADF - Not A Valid Message Queue
985   */
986
987  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
988  status = mq_notify( Test_q[CLOSED].mq, NULL );
989  fatal_posix_service_status( status, -1, "mq_ error return status");
990  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
991
992  /*
993   * Create ...
994   */
995
996  /*
997   * XXX setup notification
998   */
999  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
1047void 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
1134void 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
1191void 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
1225void 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
1239void 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
1270void 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
1284static 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
1307static 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
1360void *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
1391void *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
1410void *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
1430void *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
1451void *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
1490void *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}
Note: See TracBrowser for help on using the repository browser.