mirror of
https://github.com/azure-rtos/threadx
synced 2025-01-30 08:02:57 +08:00
205 lines
9.2 KiB
C
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);
|
|
}
|