in FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_mqueue.c [494:607]
mqd_t mq_open( const char * name,
int oflag,
mode_t mode,
struct mq_attr * attr )
{
mqd_t xMessageQueue = NULL;
size_t xNameLength = 0;
/* Default mq_attr. */
struct mq_attr xQueueCreationAttr =
{
.mq_flags = 0,
.mq_maxmsg = posixconfigMQ_MAX_MESSAGES,
.mq_msgsize = posixconfigMQ_MAX_SIZE,
.mq_curmsgs = 0
};
/* Silence warnings about unused parameters. */
( void ) mode;
/* Initialize the queue list, if needed. */
prvInitializeQueueList();
/* Check queue name. */
if( prvValidateQueueName( name, &xNameLength ) == pdFALSE )
{
/* Invalid name. */
errno = EINVAL;
xMessageQueue = ( mqd_t ) -1;
}
/* Check attributes, if given. */
if( xMessageQueue == NULL )
{
if( ( oflag & O_CREAT ) && ( attr != NULL ) && ( ( attr->mq_maxmsg <= 0 ) || ( attr->mq_msgsize <= 0 ) ) )
{
/* Invalid mq_attr.mq_maxmsg or mq_attr.mq_msgsize. */
errno = EINVAL;
xMessageQueue = ( mqd_t ) -1;
}
}
if( xMessageQueue == NULL )
{
/* Lock the mutex that guards access to the queue list. This call will
* never fail because it blocks forever. */
( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &xQueueListMutex, portMAX_DELAY );
/* Search the queue list to check if the queue exists. */
if( prvFindQueueInList( ( QueueListElement_t ** ) &xMessageQueue,
name,
( mqd_t ) NULL ) == pdTRUE )
{
/* If the mq exists, check that this function wasn't called with
* O_CREAT and O_EXCL. */
if( ( oflag & O_EXCL ) && ( oflag & O_CREAT ) )
{
errno = EEXIST;
xMessageQueue = ( mqd_t ) -1;
}
else
{
/* Check if the mq has been unlinked and is pending removal. */
if( ( ( QueueListElement_t * ) xMessageQueue )->xPendingUnlink == pdTRUE )
{
/* Queue pending deletion. Don't allow it to be re-opened. */
errno = EINVAL;
xMessageQueue = ( mqd_t ) -1;
}
else
{
/* Increase count of open file descriptors for queue. */
( ( QueueListElement_t * ) xMessageQueue )->xOpenDescriptors++;
}
}
}
/* Queue does not exist. */
else
{
/* Only create the new queue if O_CREAT was specified. */
if( oflag & O_CREAT )
{
/* Copy attributes if provided. */
if( attr != NULL )
{
xQueueCreationAttr = *attr;
}
/* Copy oflags. */
xQueueCreationAttr.mq_flags = ( long ) oflag;
/* Create the new message queue. */
if( prvCreateNewMessageQueue( ( QueueListElement_t ** ) &xMessageQueue,
&xQueueCreationAttr,
name,
xNameLength ) == pdFALSE )
{
errno = ENOSPC;
xMessageQueue = ( mqd_t ) -1;
}
}
else
{
errno = ENOENT;
xMessageQueue = ( mqd_t ) -1;
}
}
/* Release the mutex protecting the queue list. */
( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &xQueueListMutex );
}
return xMessageQueue;
}