source: rtems/testsuites/psxtests/psxmsgq01/init.c @ 3cefd8f0

4.115
Last change on this file since 3cefd8f0 was 3cefd8f0, checked in by Joel Sherrill <joel.sherrill@…>, on May 6, 2011 at 5:29:29 PM

2011-05-06 Joel Sherrill <joel.sherrill@…>

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