File indexing completed on 2025-05-11 08:24:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #ifdef HAVE_CONFIG_H
0050 #include "config.h"
0051 #endif
0052
0053 #include <rtems/posix/mqueueimpl.h>
0054 #include <rtems/score/wkspace.h>
0055 #include <rtems/sysinit.h>
0056
0057 #include <stdarg.h>
0058 #include <fcntl.h>
0059
0060 #define MQ_OPEN_FAILED ((mqd_t) -1)
0061
0062
0063
0064
0065
0066
0067
0068 static const struct mq_attr _POSIX_Message_queue_Default_attributes = {
0069 .mq_maxmsg = 10,
0070 .mq_msgsize = 16
0071 };
0072
0073 static mqd_t _POSIX_Message_queue_Create(
0074 const char *name_arg,
0075 size_t name_len,
0076 int oflag,
0077 const struct mq_attr *attr
0078 )
0079 {
0080 POSIX_Message_queue_Control *the_mq;
0081 char *name;
0082 Status_Control status;
0083
0084
0085
0086 if ( attr->mq_maxmsg <= 0 ){
0087 rtems_set_errno_and_return_value( EINVAL, MQ_OPEN_FAILED );
0088 }
0089
0090 if ( attr->mq_msgsize <= 0 ){
0091 rtems_set_errno_and_return_value( EINVAL, MQ_OPEN_FAILED );
0092 }
0093
0094 the_mq = _POSIX_Message_queue_Allocate_unprotected();
0095 if ( !the_mq ) {
0096 rtems_set_errno_and_return_value( ENFILE, MQ_OPEN_FAILED );
0097 }
0098
0099
0100
0101
0102
0103 name = _Workspace_String_duplicate( name_arg, name_len );
0104 if ( !name ) {
0105 _POSIX_Message_queue_Free( the_mq );
0106 rtems_set_errno_and_return_value( ENOMEM, MQ_OPEN_FAILED );
0107 }
0108
0109 the_mq->open_count = 1;
0110 the_mq->linked = true;
0111 the_mq->oflag = oflag;
0112
0113
0114
0115
0116
0117
0118
0119
0120 status = _CORE_message_queue_Initialize(
0121 &the_mq->Message_queue,
0122 CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
0123 attr->mq_maxmsg,
0124 attr->mq_msgsize,
0125 _CORE_message_queue_Workspace_allocate,
0126 NULL
0127 );
0128
0129 if ( status != STATUS_SUCCESSFUL ) {
0130 _POSIX_Message_queue_Free( the_mq );
0131 _Workspace_Free( name );
0132 rtems_set_errno_and_return_value( ENOSPC, MQ_OPEN_FAILED );
0133 }
0134
0135 _Objects_Open_string(
0136 &_POSIX_Message_queue_Information,
0137 &the_mq->Object,
0138 name
0139 );
0140 return the_mq->Object.id;
0141 }
0142
0143
0144
0145
0146 mqd_t mq_open(
0147 const char *name,
0148 int oflag,
0149 ...
0150
0151
0152 )
0153 {
0154 POSIX_Message_queue_Control *the_mq;
0155 size_t name_len;
0156 Objects_Get_by_name_error error;
0157 mqd_t status;
0158
0159 _Objects_Allocator_lock();
0160 the_mq = _POSIX_Message_queue_Get_by_name( name, &name_len, &error );
0161
0162
0163
0164
0165
0166
0167
0168 if ( the_mq == NULL ) {
0169 va_list ap;
0170 const struct mq_attr *attr;
0171
0172
0173
0174
0175
0176
0177 if ( error != OBJECTS_GET_BY_NAME_NO_OBJECT || ( oflag & O_CREAT ) == 0 ) {
0178 _Objects_Allocator_unlock();
0179 rtems_set_errno_and_return_value(
0180 _POSIX_Get_by_name_error( error ),
0181 MQ_OPEN_FAILED
0182 );
0183 }
0184
0185 va_start( ap, oflag );
0186 va_arg( ap, mode_t );
0187 attr = va_arg( ap, const struct mq_attr * );
0188 va_end( ap );
0189
0190 if ( attr == NULL ) {
0191 attr = &_POSIX_Message_queue_Default_attributes;
0192 }
0193
0194
0195
0196
0197
0198
0199 status = _POSIX_Message_queue_Create( name, name_len, oflag, attr );
0200 } else {
0201
0202
0203
0204
0205
0206 if ( ( oflag & ( O_CREAT | O_EXCL ) ) == ( O_CREAT | O_EXCL ) ) {
0207 _Objects_Allocator_unlock();
0208 rtems_set_errno_and_return_value( EEXIST, MQ_OPEN_FAILED );
0209 }
0210
0211 the_mq->open_count += 1;
0212 status = the_mq->Object.id;
0213 }
0214
0215 _Objects_Allocator_unlock();
0216 return status;
0217 }
0218
0219 static void _POSIX_Message_queue_Manager_initialization( void )
0220 {
0221 _Objects_Initialize_information( &_POSIX_Message_queue_Information );
0222 }
0223
0224 RTEMS_SYSINIT_ITEM(
0225 _POSIX_Message_queue_Manager_initialization,
0226 RTEMS_SYSINIT_POSIX_MESSAGE_QUEUE,
0227 RTEMS_SYSINIT_ORDER_MIDDLE
0228 );