📄 init.c
字号:
/* * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. * * $Id: init.c,v 1.9.2.4 2004/03/05 15:49:39 joel Exp $ */#define CONFIGURE_INIT#include "system.h"#include <sched.h>#include <fcntl.h>#include <time.h>#include <tmacros.h>#include <signal.h> /* signal facilities */typedef struct { char msg[ 50 ]; int size; unsigned int priority;}Test_Message_t;Test_Message_t Predefined_Msgs[MAXMSG+1];Test_Message_t Predefined_Msgs[MAXMSG+1] = { { "12345678", 9, MQ_PRIO_MAX-1 }, /* Max Length Message med */ { "", 1, 1 }, /* NULL Message low */ { "Last", 5, MQ_PRIO_MAX }, /* Queue Full Message hi */ { "No Message", 0, MQ_PRIO_MAX-1 }, /* 0 length Message med */ { "1", 2, 0 }, /* Cause Overflow Behavior */};int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };typedef struct { mqd_t mq; Test_Queue_Types index; char *name; int oflag; int maxmsg; int msgsize; int count;} Test_queue_type;Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES ] = { { 0, 0, "Qread", ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 }, { 0, 1, "Qwrite", ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 }, { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 }, { 0, 3, "Qblock", ( O_CREAT | O_RDWR ) , MAXMSG, MSGSIZE, 0 }, { 0, 4, "Qdefault", ( O_CREAT | O_RDWR ) , 10, 16, 0 }, { 0, 5, "mq6", ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },};#define RW_NAME Test_q[ RW_QUEUE ].name#define DEFAULT_NAME Test_q[ DEFAULT_RW ].name#define RD_NAME Test_q[ RD_QUEUE ].name#define WR_NAME Test_q[ WR_QUEUE ].name#define BLOCKING_NAME Test_q[ BLOCKING ].name#define CLOSED_NAME Test_q[ CLOSED ].name#define RW_ATTR Test_q[ RW_QUEUE ].oflag#define DEFAULT_ATTR Test_q[ DEFAULT_RW ].oflag#define RD_ATTR Test_q[ RD_QUEUE ].oflag#define WR_ATTR Test_q[ WR_QUEUE ].oflag#define BLOCK_ATTR Test_q[ BLOCKING ].oflag#define CLOSED_ATTR Test_q[ CLOSED ].oflag/* * Outputs a header at each test section. */void Start_Test( char *description){ printf( "_______________%s\n", description );}void Validate_attributes( mqd_t mq, int oflag, int msg_count){ int status; struct mq_attr attr; status = mq_getattr( mq, &attr ); fatal_posix_service_status( status, 0, "mq_getattr valid return status"); if ( mq != Test_q[ DEFAULT_RW ].mq ){ fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" ); fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute"); } fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" ); fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );}char Queue_Name[PATH_MAX + 2];#define Get_Queue_Name( i ) Test_q[i].namechar *Build_Queue_Name( int i ) { sprintf(Queue_Name,"mq%d", i+1 ); return Queue_Name;}char *Get_Too_Long_Name(){ int i; for ( i=0; i< PATH_MAX+1; i++ ) Queue_Name[i] = 'N'; Queue_Name[i] = '\0'; return Queue_Name;}void open_test_queues(){ struct mq_attr attr; int status; Test_queue_type *tq; int que; attr.mq_maxmsg = MAXMSG; attr.mq_msgsize = MSGSIZE; puts( "Init: Open Test Queues" ); for( que = 0; que < NUMBER_OF_TEST_QUEUES; que++ ) { tq = &Test_q[ que ]; if ( que == DEFAULT_RW) Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL ); else Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr ); assert( Test_q[que].mq != (-1) ); } status = mq_close( Test_q[CLOSED].mq ); fatal_posix_service_status( status, 0, "mq_close message queue"); status = mq_unlink( CLOSED_NAME ); fatal_posix_service_status( status, 0, "mq_unlink message queue"); }/* * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues * opened but closes the rest. */void validate_mq_open_error_codes(){ int i; mqd_t n_mq2; struct mq_attr attr; int status; mqd_t open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1]; attr.mq_maxmsg = MAXMSG; attr.mq_msgsize = MSGSIZE; Start_Test( "mq_open errors" ); /* * XXX EINVAL - inappropriate name was given for the message queue */ /* * EINVAL - Create with negative maxmsg. */ attr.mq_maxmsg = -1; puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" ); n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr); fatal_posix_service_status( (int) n_mq2, (int ) (-1), "mq_open error return status" ); fatal_posix_service_status( errno, EINVAL, "mq_open errno EINVAL"); attr.mq_maxmsg = MAXMSG; /* * EINVAL - Create withnegative msgsize. */ attr.mq_msgsize = -1; puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" ); n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr); fatal_posix_service_status( (int) n_mq2, (int ) (-1), "mq_open error return status" ); fatal_posix_service_status( errno, EINVAL, "mq_open errno EINVAL"); attr.mq_msgsize = MSGSIZE; /* * ENOENT - Open a non-created file. */ puts( "Init: mq_open - Open new mq without create flag (ENOENT)" ); n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL); fatal_posix_service_status( (int) n_mq2, (int ) (-1), "mq_open error return status" ); fatal_posix_service_status( errno, ENOENT, "mq_open errno ENOENT"); /* * XXX EINTR - call was interrupted by a signal */ /* * ENAMETOOLONG - Give a name greater than PATH_MAX. */ puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" ); n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL ); fatal_posix_service_status( (int) n_mq2, (int ) (-1), "mq_open error return status" ); fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG"); /* * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX * Per implementation not possible. */ /* * EEXIST - Create an existing queue. */ puts( "Init: mq_open - Create an Existing mq (EEXIST)" ); open_mq[0] = mq_open( Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL ); assert( open_mq[0] != (-1) ); n_mq2 = mq_open( Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL); fatal_posix_service_status( (int) n_mq2, (int ) (-1), "mq_open error return status" ); fatal_posix_service_status( errno, EEXIST, "mq_open errno EEXIST"); status = mq_unlink( Build_Queue_Name(0) ); fatal_posix_service_status( status, 0, "mq_unlink message queue"); status = mq_close( open_mq[0]); fatal_posix_service_status( status, 0, "mq_close message queue"); /* * Open maximum number of message queues */ puts( "Init: mq_open - SUCCESSFUL" ); for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) { open_mq[i] = mq_open( Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL ); assert( open_mq[i] != (-1) ); assert( open_mq[i] ); /*XXX - Isn't there a more general check */ /* JRS printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */ } /* * XXX EACCES - permission to create is denied. */ /* * XXX EACCES - queue exists permissions specified by o_flag are denied. */ /* * XXX EMFILE - Too many message queues in use by the process */ /* * ENFILE - Too many message queues open in the system */ puts( "Init: mq_open - system is out of resources (ENFILE)" ); n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL ); fatal_posix_service_status( (int) n_mq2, (int ) (-1), "mq_open error return status" ); fatal_posix_service_status( errno, ENFILE, "mq_open errno ENFILE"); /* * Unlink and Close all queues. */ puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" ); for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) { status = mq_close( open_mq[i]); fatal_posix_service_status( status, 0, "mq_close message queue"); status = mq_unlink( Build_Queue_Name(i) ); if ( status == -1 ) perror( "mq_unlink" ); fatal_posix_service_status( status, 0, "mq_unlink message queue"); /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */ }}void validate_mq_unlink_error_codes(){ int status; Start_Test( "mq_unlink errors" ); /* * XXX - EACCES Permission Denied */ /* * ENAMETOOLONG - Give a name greater than PATH_MAX. */ puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" ); status = mq_unlink( Get_Too_Long_Name() ); fatal_posix_service_status( status, -1, "mq_unlink error return status"); fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG"); /* * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX * Per implementation not possible. */ /* * ENOENT - Unlink an unopened queue */ puts( "Init: mq_unlink - A Queue not opened (ENOENT)" ); status = mq_unlink( CLOSED_NAME ); fatal_posix_service_status( status, -1, "mq_unlink error return status"); fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT"); /* * XXX - The following were not listed in the POSIX document as * possible errors. Under other commands the EINVAL is * given for these conditions. */ /* * EINVAL - Unlink a queue with no name */ puts( "Init: mq_unlink (NULL) - EINVAL" ); status = mq_unlink( NULL ); fatal_posix_service_status( status, -1, "mq_unlink error return status"); fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value"); /* * EINVAL - Unlink a queue with a null name */ puts( "Init: mq_unlink (\"\") - EINVAL" ); status = mq_unlink( "" ); fatal_posix_service_status( status, -1, "mq_unlink error return status"); fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value"); }void validate_mq_close_error_codes(){ int status; Start_Test( "mq_close errors" ); /* * EBADF - Close a queue that is not open. */ puts( "Init: mq_close - unopened queue (EBADF)" ); status = mq_close( Test_q[CLOSED].mq ); fatal_posix_service_status( status, -1, "mq_close error return status"); fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");} void validate_mq_getattr_error_codes(){ struct mq_attr attr; int status; Start_Test( "mq_getattr errors" ); /* * EBADF - Get the attributes from a closed queue. */ puts( "Init: mq_getattr - unopened queue (EBADF)" ); status = mq_getattr( Test_q[CLOSED].mq, &attr ); fatal_posix_service_status( status, -1, "mq_close error return status"); fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF"); /* * XXX - The following are not listed in the POSIX manual but * may occur. */ /* * EINVAL - NULL attributes */ puts( "Init: mq_getattr - NULL attributes (EINVAL)" ); status = mq_getattr( Test_q[RW_QUEUE].mq, NULL ); fatal_posix_service_status( status, -1, "mq_close error return status"); fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL"); }void Send_msg_to_que( int que, int msg){ Test_Message_t *ptr = &Predefined_Msgs[msg]; int status; status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority ); fatal_posix_service_status( status, 0, "mq_send valid return status"); Test_q[que].count++;}void Show_send_msg_to_que( char *task_name, int que, int msg){ Test_Message_t *ptr = &Predefined_Msgs[msg]; printf( "%s mq_send - to %s msg: %s priority %d\n", task_name, Test_q[que].name, ptr->msg, ptr->priority); Send_msg_to_que( que, msg );}void verify_queues_full( char *task_name){ int que; /* * Validate that the queues are full. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -