1
0
mirror of https://github.com/azure-rtos/threadx synced 2025-01-30 08:02:57 +08:00
2022-10-26 23:41:13 +00:00

205 lines
9.2 KiB
C

/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** POSIX wrapper for THREADX */
/** */
/** */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#include "tx_api.h" /* Threadx API */
#include "pthread.h" /* Posix API */
#include "px_int.h" /* Posix helper functions */
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* mq_open PORTABLE C */
/* 6.2.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This routine establishes connection between a named message queue */
/* and the calling a thread */
/* */
/* INPUT */
/* */
/* mqName name of the queue to open. */
/* oflags O_RDONLY, O_WRONLY, O_RDWR, or O_CREAT, */
/* O_EXCEL,O_NONBLOCK. */
/* extra optional parameters. */
/* */
/* OUTPUT */
/* */
/* queue_des If successful */
/* ERROR If fails */
/* */
/* CALLS */
/* */
/* posix_find_queue find queue of given name */
/* posix_mq_create create a queue */
/* posix_get_queue_des gets a queue-descriptor for Queue */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */
/* 10-31-2022 Scott Larson Update comparison with NULL, */
/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
mqd_t mq_open(const CHAR * mqName, ULONG oflags,...)
{
POSIX_MSG_QUEUE *posix_queue;
struct mq_des *queue_des;
struct mq_attr *q_attr;
mode_t mode;
va_list create_queue;
ULONG len;
ULONG temp1;
len = strlen(mqName);
if(len > PATH_MAX)
{
/* Return error. */
posix_errno = ENAMETOOLONG;
posix_set_pthread_errno(ENAMETOOLONG);
/*. Return error. */
return((struct mq_des *)ERROR);
}
switch(oflags & 0xFF00)
{
case O_CREAT:
case (O_EXCL | O_CREAT):
va_start(create_queue, oflags);
mode = va_arg(create_queue, mode_t);
mode = mode; /* just to keep the complier happy */
q_attr = va_arg(create_queue, struct mq_attr *);
va_end(create_queue);
/* Check for valid messages and its size. */
if(!q_attr || q_attr->mq_maxmsg > MQ_MAXMSG || q_attr->mq_msgsize > MQ_MSGSIZE)
{
/* return POSIX error.for invalid oflag. */
posix_errno = EINVAL;
posix_set_pthread_errno(EINVAL);
/* return error. */
return ((struct mq_des *)ERROR);
}
/* Check if name is exist. NULL if successful. */
if((posix_queue = posix_find_queue(mqName)) != NULL)
{
if(posix_queue->unlink_flag == TX_TRUE)
{
/* return POSIX error. */
posix_errno = ENOENT;
posix_set_pthread_errno(ENOENT);
/* return error. */
return ((struct mq_des *)ERROR);
}
/* Set Posix error if name exist. */
posix_errno = EEXIST;
posix_set_pthread_errno(EEXIST);
/* return error */
return((struct mq_des *)ERROR);
}
/* If q_attr is NULL then the default attributes of the struct
mq_attr are used */
if(q_attr == NULL)
{
q_attr = &(posix_qattr_default);
temp1 = q_attr->mq_maxmsg;
temp1= temp1 ; /* Just to keep complier happy */
}
/* Create a queue which returns posix queue if successful and
NULL if fails. */
if(!(posix_queue = posix_mq_create(mqName, q_attr)))
{
/* posix_errno is filled up in mq_create. */
return((struct mq_des *)ERROR);
}
/* open count incremented by one. */
posix_queue->open_count += 1;
break;
case O_EXCL:
/* Check if name is exist. NULL if successful. */
if(!(posix_queue = posix_find_queue(mqName)))
{
/* return POSIX error. */
posix_errno = EBADF;
posix_set_pthread_errno(EBADF);
/* return error. */
return ((struct mq_des *)ERROR);
}
return(OK);
case O_RDONLY:
case O_WRONLY:
case O_RDWR:
case O_NONBLOCK:
/* Check if name is exist. NULL if successful. */
if((posix_queue = posix_find_queue(mqName)) != NULL)
{
if(posix_queue->unlink_flag == TX_TRUE)
{
/* return POSIX error. */
posix_errno = ENOENT;
posix_set_pthread_errno(ENOENT);
/* return error. */
return ((struct mq_des *)ERROR);
}
/* open count incremented by one. */
posix_queue->open_count += 1;
}
break;
default:
/* return POSIX error.for invalid oflag. */
posix_errno = EINVAL;
posix_set_pthread_errno(EINVAL);
/* return error. */
return ((struct mq_des *)ERROR);
}
queue_des = posix_get_queue_des(posix_queue);
/* Store the flags. */
queue_des->f_flag = oflags;
return(queue_des);
}