forked from Imagelibrary/rtems
Split mqueue.c into a variety of files.
This commit is contained in:
@@ -22,6 +22,11 @@ BUILD_FOR_NOW_C_PIECES = aio cancel mqueue semaphore utsname
|
|||||||
ENOSYS_C_PIECES = execl execle execlp execv execve execvp fork pthreadatfork \
|
ENOSYS_C_PIECES = execl execle execlp execv execve execvp fork pthreadatfork \
|
||||||
wait waitpid
|
wait waitpid
|
||||||
|
|
||||||
|
MESSAGE_QUEUE_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \
|
||||||
|
mqueuegetattr mqueuenametoid mqueuenotify mqueueopen mqueuereceive \
|
||||||
|
mqueuerecvsupp mqueuesend mqueuesendsupp mqueuesetattr \
|
||||||
|
mqueuetimedreceive mqueuetimedsend mqueueunlink \
|
||||||
|
|
||||||
PTHREAD_C_PIECES = pthread pthreadsetcputime pthreadgetcputime \
|
PTHREAD_C_PIECES = pthread pthreadsetcputime pthreadgetcputime \
|
||||||
pthreadgetcpuclockid pthreadonce pthreadequal pthreadself pthreadexit \
|
pthreadgetcpuclockid pthreadonce pthreadequal pthreadself pthreadexit \
|
||||||
pthreaddetach pthreadjoin pthreadcreate pthreadattrsetdetachstate \
|
pthreaddetach pthreadjoin pthreadcreate pthreadattrsetdetachstate \
|
||||||
@@ -38,7 +43,8 @@ PSIGNAL_C_PIECES = psignal alarm kill killinfo pause pthreadkill \
|
|||||||
sigismember sigpending sigprocmask sigqueue sigsuspend sigtimedwait \
|
sigismember sigpending sigprocmask sigqueue sigsuspend sigtimedwait \
|
||||||
sigwait sigwaitinfo signal_2
|
sigwait sigwaitinfo signal_2
|
||||||
|
|
||||||
C_PIECES = adasupp cond getpid key mutex $(PTHREAD_C_PIECES) \
|
C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \
|
||||||
|
mutex $(PTHREAD_C_PIECES) \
|
||||||
$(PSIGNAL_C_PIECES) ptimer sched time types unistd $(ENOSYS_C_PIECES) \
|
$(PSIGNAL_C_PIECES) ptimer sched time types unistd $(ENOSYS_C_PIECES) \
|
||||||
$(BUILD_FOR_NOW_C_PIECES)
|
$(BUILD_FOR_NOW_C_PIECES)
|
||||||
|
|
||||||
|
|||||||
@@ -55,675 +55,3 @@ void _POSIX_Message_queue_Manager_initialization(
|
|||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Create_support
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Message_queue_Create_support(
|
|
||||||
const char *name,
|
|
||||||
int pshared,
|
|
||||||
unsigned int oflag,
|
|
||||||
struct mq_attr *attr,
|
|
||||||
POSIX_Message_queue_Control **message_queue
|
|
||||||
)
|
|
||||||
{
|
|
||||||
POSIX_Message_queue_Control *the_mq;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Allocate();
|
|
||||||
|
|
||||||
if ( !the_mq ) {
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( ENFILE );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( pshared == PTHREAD_PROCESS_SHARED &&
|
|
||||||
!( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
|
|
||||||
the_mq->Object.id, FALSE ) ) ) {
|
|
||||||
_POSIX_Message_queue_Free( the_mq );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( ENFILE );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
the_mq->process_shared = pshared;
|
|
||||||
|
|
||||||
if ( name ) {
|
|
||||||
the_mq->named = TRUE;
|
|
||||||
the_mq->open_count = 1;
|
|
||||||
the_mq->linked = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
the_mq->named = FALSE;
|
|
||||||
|
|
||||||
if ( oflag & O_NONBLOCK )
|
|
||||||
the_mq->blocking = FALSE;
|
|
||||||
else
|
|
||||||
the_mq->blocking = TRUE;
|
|
||||||
|
|
||||||
/* XXX
|
|
||||||
*
|
|
||||||
* Note that this should be based on the current scheduling policy.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX
|
|
||||||
*
|
|
||||||
* Message and waiting disciplines are not distinguished.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
the_mq_attr->message_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
|
||||||
the_mq_attr->waiting_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
|
||||||
*/
|
|
||||||
|
|
||||||
the_mq->Message_queue.Attributes.discipline =
|
|
||||||
CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
|
||||||
|
|
||||||
if ( ! _CORE_message_queue_Initialize(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
OBJECTS_POSIX_MESSAGE_QUEUES,
|
|
||||||
&the_mq->Message_queue.Attributes,
|
|
||||||
attr->mq_maxmsg,
|
|
||||||
attr->mq_msgsize,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_POSIX_Message_queue_MP_Send_extract_proxy
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
) ) {
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( pshared == PTHREAD_PROCESS_SHARED )
|
|
||||||
_Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_POSIX_Message_queue_Free( the_mq );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( ENOSPC );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* XXX - need Names to be a string!!! */
|
|
||||||
_Objects_Open(
|
|
||||||
&_POSIX_Message_queue_Information,
|
|
||||||
&the_mq->Object,
|
|
||||||
(char *) name
|
|
||||||
);
|
|
||||||
|
|
||||||
*message_queue = the_mq;
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( pshared == PTHREAD_PROCESS_SHARED )
|
|
||||||
_POSIX_Message_queue_MP_Send_process_packet(
|
|
||||||
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
|
|
||||||
the_mq->Object.id,
|
|
||||||
(char *) name,
|
|
||||||
0 /* Not used */
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
|
|
||||||
*/
|
|
||||||
|
|
||||||
mqd_t mq_open(
|
|
||||||
const char *name,
|
|
||||||
int oflag,
|
|
||||||
...
|
|
||||||
/* mode_t mode, */
|
|
||||||
/* struct mq_attr attr */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
va_list arg;
|
|
||||||
mode_t mode;
|
|
||||||
struct mq_attr *attr;
|
|
||||||
int status;
|
|
||||||
Objects_Id the_mq_id;
|
|
||||||
POSIX_Message_queue_Control *the_mq;
|
|
||||||
|
|
||||||
if ( oflag & O_CREAT ) {
|
|
||||||
va_start(arg, oflag);
|
|
||||||
mode = (mode_t) va_arg( arg, mode_t * );
|
|
||||||
attr = (struct mq_attr *) va_arg( arg, struct mq_attr ** );
|
|
||||||
va_end(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the name to id translation worked, then the message queue exists
|
|
||||||
* and we can just return a pointer to the id. Otherwise we may
|
|
||||||
* need to check to see if this is a "message queue does not exist"
|
|
||||||
* or some other miscellaneous error on the name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( status ) {
|
|
||||||
|
|
||||||
if ( status == EINVAL ) { /* name -> ID translation failed */
|
|
||||||
if ( !(oflag & O_CREAT) ) { /* willing to create it? */
|
|
||||||
set_errno_and_return_minus_one( ENOENT );
|
|
||||||
return (mqd_t) -1;
|
|
||||||
}
|
|
||||||
/* we are willing to create it */
|
|
||||||
}
|
|
||||||
set_errno_and_return_minus_one( status ); /* some type of error */
|
|
||||||
return (mqd_t) -1;
|
|
||||||
|
|
||||||
} else { /* name -> ID translation succeeded */
|
|
||||||
|
|
||||||
if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
|
|
||||||
set_errno_and_return_minus_one( EEXIST );
|
|
||||||
return (mqd_t) -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX In this case we need to do an ID->pointer conversion to
|
|
||||||
* check the mode. This is probably a good place for a subroutine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
the_mq->open_count += 1;
|
|
||||||
|
|
||||||
return (mqd_t)&the_mq->Object.id;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX verify this comment...
|
|
||||||
*
|
|
||||||
* At this point, the message queue does not exist and everything has been
|
|
||||||
* checked. We should go ahead and create a message queue.
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = _POSIX_Message_queue_Create_support(
|
|
||||||
name,
|
|
||||||
TRUE, /* shared across processes */
|
|
||||||
oflag,
|
|
||||||
attr,
|
|
||||||
&the_mq
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( status == -1 )
|
|
||||||
return (mqd_t) -1;
|
|
||||||
|
|
||||||
return (mqd_t) &the_mq->Object.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Delete
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _POSIX_Message_queue_Delete(
|
|
||||||
POSIX_Message_queue_Control *the_mq
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !the_mq->linked && !the_mq->open_count ) {
|
|
||||||
_POSIX_Message_queue_Free( the_mq );
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
|
|
||||||
|
|
||||||
_Objects_MP_Close(
|
|
||||||
&_POSIX_Message_queue_Information,
|
|
||||||
the_mq->Object.id
|
|
||||||
);
|
|
||||||
|
|
||||||
_POSIX_Message_queue_MP_Send_process_packet(
|
|
||||||
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
|
|
||||||
the_mq->Object.id,
|
|
||||||
0, /* Not used */
|
|
||||||
0 /* Not used */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_close(
|
|
||||||
mqd_t mqdes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
the_mq->open_count -= 1;
|
|
||||||
_POSIX_Message_queue_Delete( the_mq );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_unlink(
|
|
||||||
const char *name
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Id the_mq_id;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
|
||||||
|
|
||||||
if ( !status )
|
|
||||||
set_errno_and_return_minus_one( status );
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( the_mq_id, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_Objects_MP_Close(
|
|
||||||
&_POSIX_Message_queue_Information,
|
|
||||||
the_mq->Object.id
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
the_mq->linked = FALSE;
|
|
||||||
|
|
||||||
_POSIX_Message_queue_Delete( the_mq );
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Send_support
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Message_queue_Send_support(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const char *msg_ptr,
|
|
||||||
unsigned32 msg_len,
|
|
||||||
Priority_Control msg_prio,
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/* XXX must add support for timeout and priority */
|
|
||||||
_CORE_message_queue_Send(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
(void *) msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
mqdes,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
NULL /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return _Thread_Executing->Wait.return_code;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_send(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int msg_prio
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Send_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_timedsend(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int msg_prio,
|
|
||||||
const struct timespec *timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Send_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Receive_support
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX be careful ... watch the size going through all the layers ... */
|
|
||||||
|
|
||||||
ssize_t _POSIX_Message_queue_Receive_support(
|
|
||||||
mqd_t mqdes,
|
|
||||||
char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int *msg_prio,
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
unsigned32 status = 0;
|
|
||||||
unsigned32 length_out;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/* XXX need to define the options argument to this */
|
|
||||||
length_out = msg_len;
|
|
||||||
_CORE_message_queue_Seize(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
&length_out,
|
|
||||||
/* msg_prio, XXXX */
|
|
||||||
the_mq->blocking,
|
|
||||||
timeout
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
if ( !status )
|
|
||||||
return length_out;
|
|
||||||
/* XXX --- the return codes gotta be looked at .. fix this */
|
|
||||||
return _Thread_Executing->Wait.return_code;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
|
||||||
*/
|
|
||||||
|
|
||||||
ssize_t mq_receive(
|
|
||||||
mqd_t mqdes,
|
|
||||||
char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int *msg_prio
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Receive_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_timedreceive( /* XXX: should this be ssize_t */
|
|
||||||
mqd_t mqdes,
|
|
||||||
char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int *msg_prio,
|
|
||||||
const struct timespec *timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Receive_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Notify_handler
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _POSIX_Message_queue_Notify_handler(
|
|
||||||
void *user_data
|
|
||||||
)
|
|
||||||
{
|
|
||||||
POSIX_Message_queue_Control *the_mq;
|
|
||||||
|
|
||||||
the_mq = user_data;
|
|
||||||
|
|
||||||
/* XXX do something with signals here!!!! */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.6 Notify Process that a Message is Available on a Queue,
|
|
||||||
* P1003.1b-1993, p. 280
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_notify(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const struct sigevent *notification
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EBADF );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
if ( notification ) {
|
|
||||||
if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( EBUSY );
|
|
||||||
}
|
|
||||||
|
|
||||||
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
|
||||||
|
|
||||||
the_mq->notification = *notification;
|
|
||||||
|
|
||||||
_CORE_message_queue_Set_notify(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
_POSIX_Message_queue_Notify_handler,
|
|
||||||
the_mq
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_setattr(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const struct mq_attr *mqstat,
|
|
||||||
struct mq_attr *omqstat
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
CORE_message_queue_Attributes *the_mq_attr;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/*
|
|
||||||
* Return the old values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX this is the same stuff as is in mq_getattr... and probably */
|
|
||||||
/* XXX should be in an inlined private routine */
|
|
||||||
|
|
||||||
the_mq_attr = &the_mq->Message_queue.Attributes;
|
|
||||||
|
|
||||||
omqstat->mq_flags = the_mq->flags;
|
|
||||||
omqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
|
||||||
omqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
|
||||||
omqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ignore everything except the O_NONBLOCK bit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( mqstat->mq_flags & O_NONBLOCK )
|
|
||||||
the_mq->blocking = FALSE;
|
|
||||||
else
|
|
||||||
the_mq->blocking = TRUE;
|
|
||||||
|
|
||||||
the_mq->flags = mqstat->mq_flags;
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_getattr(
|
|
||||||
mqd_t mqdes,
|
|
||||||
struct mq_attr *mqstat
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
CORE_message_queue_Attributes *the_mq_attr;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/*
|
|
||||||
* Return the old values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX this is the same stuff as is in mq_setattr... and probably */
|
|
||||||
/* XXX should be in an inlined private routine */
|
|
||||||
|
|
||||||
the_mq_attr = &the_mq->Message_queue.Attributes;
|
|
||||||
|
|
||||||
mqstat->mq_flags = the_mq->flags;
|
|
||||||
mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
|
||||||
mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
|
||||||
mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Name_to_id
|
|
||||||
*
|
|
||||||
* XXX
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Message_queue_Name_to_id(
|
|
||||||
const char *name,
|
|
||||||
Objects_Id *id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return 0; /* XXX fill me in */
|
|
||||||
}
|
|
||||||
|
|||||||
58
c/src/exec/posix/src/mqueueclose.c
Normal file
58
c/src/exec/posix/src/mqueueclose.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_close(
|
||||||
|
mqd_t mqdes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
the_mq->open_count -= 1;
|
||||||
|
_POSIX_Message_queue_Delete( the_mq );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
143
c/src/exec/posix/src/mqueuecreatesupp.c
Normal file
143
c/src/exec/posix/src/mqueuecreatesupp.c
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Create_support
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Message_queue_Create_support(
|
||||||
|
const char *name,
|
||||||
|
int pshared,
|
||||||
|
unsigned int oflag,
|
||||||
|
struct mq_attr *attr,
|
||||||
|
POSIX_Message_queue_Control **message_queue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
POSIX_Message_queue_Control *the_mq;
|
||||||
|
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Allocate();
|
||||||
|
|
||||||
|
if ( !the_mq ) {
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( ENFILE );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( pshared == PTHREAD_PROCESS_SHARED &&
|
||||||
|
!( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
|
||||||
|
the_mq->Object.id, FALSE ) ) ) {
|
||||||
|
_POSIX_Message_queue_Free( the_mq );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( ENFILE );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
the_mq->process_shared = pshared;
|
||||||
|
|
||||||
|
if ( name ) {
|
||||||
|
the_mq->named = TRUE;
|
||||||
|
the_mq->open_count = 1;
|
||||||
|
the_mq->linked = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
the_mq->named = FALSE;
|
||||||
|
|
||||||
|
if ( oflag & O_NONBLOCK )
|
||||||
|
the_mq->blocking = FALSE;
|
||||||
|
else
|
||||||
|
the_mq->blocking = TRUE;
|
||||||
|
|
||||||
|
/* XXX
|
||||||
|
*
|
||||||
|
* Note that this should be based on the current scheduling policy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX
|
||||||
|
*
|
||||||
|
* Message and waiting disciplines are not distinguished.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
the_mq_attr->message_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||||
|
the_mq_attr->waiting_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||||
|
*/
|
||||||
|
|
||||||
|
the_mq->Message_queue.Attributes.discipline =
|
||||||
|
CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||||
|
|
||||||
|
if ( ! _CORE_message_queue_Initialize(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
OBJECTS_POSIX_MESSAGE_QUEUES,
|
||||||
|
&the_mq->Message_queue.Attributes,
|
||||||
|
attr->mq_maxmsg,
|
||||||
|
attr->mq_msgsize,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_POSIX_Message_queue_MP_Send_extract_proxy
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
) ) {
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( pshared == PTHREAD_PROCESS_SHARED )
|
||||||
|
_Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_POSIX_Message_queue_Free( the_mq );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( ENOSPC );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX - need Names to be a string!!! */
|
||||||
|
_Objects_Open(
|
||||||
|
&_POSIX_Message_queue_Information,
|
||||||
|
&the_mq->Object,
|
||||||
|
(char *) name
|
||||||
|
);
|
||||||
|
|
||||||
|
*message_queue = the_mq;
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( pshared == PTHREAD_PROCESS_SHARED )
|
||||||
|
_POSIX_Message_queue_MP_Send_process_packet(
|
||||||
|
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
|
||||||
|
the_mq->Object.id,
|
||||||
|
(char *) name,
|
||||||
|
0 /* Not used */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
62
c/src/exec/posix/src/mqueuedeletesupp.c
Normal file
62
c/src/exec/posix/src/mqueuedeletesupp.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Delete
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _POSIX_Message_queue_Delete(
|
||||||
|
POSIX_Message_queue_Control *the_mq
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !the_mq->linked && !the_mq->open_count ) {
|
||||||
|
_POSIX_Message_queue_Free( the_mq );
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
|
||||||
|
|
||||||
|
_Objects_MP_Close(
|
||||||
|
&_POSIX_Message_queue_Information,
|
||||||
|
the_mq->Object.id
|
||||||
|
);
|
||||||
|
|
||||||
|
_POSIX_Message_queue_MP_Send_process_packet(
|
||||||
|
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
|
||||||
|
the_mq->Object.id,
|
||||||
|
0, /* Not used */
|
||||||
|
0 /* Not used */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
73
c/src/exec/posix/src/mqueuegetattr.c
Normal file
73
c/src/exec/posix/src/mqueuegetattr.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_getattr(
|
||||||
|
mqd_t mqdes,
|
||||||
|
struct mq_attr *mqstat
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
CORE_message_queue_Attributes *the_mq_attr;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/*
|
||||||
|
* Return the old values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX this is the same stuff as is in mq_setattr... and probably */
|
||||||
|
/* XXX should be in an inlined private routine */
|
||||||
|
|
||||||
|
the_mq_attr = &the_mq->Message_queue.Attributes;
|
||||||
|
|
||||||
|
mqstat->mq_flags = the_mq->flags;
|
||||||
|
mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
||||||
|
mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
||||||
|
mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
44
c/src/exec/posix/src/mqueuenametoid.c
Normal file
44
c/src/exec/posix/src/mqueuenametoid.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Name_to_id
|
||||||
|
*
|
||||||
|
* XXX
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Message_queue_Name_to_id(
|
||||||
|
const char *name,
|
||||||
|
Objects_Id *id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 0; /* XXX fill me in */
|
||||||
|
}
|
||||||
97
c/src/exec/posix/src/mqueuenotify.c
Normal file
97
c/src/exec/posix/src/mqueuenotify.c
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Notify_handler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _POSIX_Message_queue_Notify_handler(
|
||||||
|
void *user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
POSIX_Message_queue_Control *the_mq;
|
||||||
|
|
||||||
|
the_mq = user_data;
|
||||||
|
|
||||||
|
/* XXX do something with signals here!!!! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.6 Notify Process that a Message is Available on a Queue,
|
||||||
|
* P1003.1b-1993, p. 280
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_notify(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const struct sigevent *notification
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EBADF );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
if ( notification ) {
|
||||||
|
if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( EBUSY );
|
||||||
|
}
|
||||||
|
|
||||||
|
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
||||||
|
|
||||||
|
the_mq->notification = *notification;
|
||||||
|
|
||||||
|
_CORE_message_queue_Set_notify(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
_POSIX_Message_queue_Notify_handler,
|
||||||
|
the_mq
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
116
c/src/exec/posix/src/mqueueopen.c
Normal file
116
c/src/exec/posix/src/mqueueopen.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
|
||||||
|
*/
|
||||||
|
|
||||||
|
mqd_t mq_open(
|
||||||
|
const char *name,
|
||||||
|
int oflag,
|
||||||
|
...
|
||||||
|
/* mode_t mode, */
|
||||||
|
/* struct mq_attr attr */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
mode_t mode;
|
||||||
|
struct mq_attr *attr;
|
||||||
|
int status;
|
||||||
|
Objects_Id the_mq_id;
|
||||||
|
POSIX_Message_queue_Control *the_mq;
|
||||||
|
|
||||||
|
if ( oflag & O_CREAT ) {
|
||||||
|
va_start(arg, oflag);
|
||||||
|
mode = (mode_t) va_arg( arg, mode_t );
|
||||||
|
attr = (struct mq_attr *) va_arg( arg, struct mq_attr * );
|
||||||
|
va_end(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the name to id translation worked, then the message queue exists
|
||||||
|
* and we can just return a pointer to the id. Otherwise we may
|
||||||
|
* need to check to see if this is a "message queue does not exist"
|
||||||
|
* or some other miscellaneous error on the name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( status ) {
|
||||||
|
|
||||||
|
if ( status == EINVAL ) { /* name -> ID translation failed */
|
||||||
|
if ( !(oflag & O_CREAT) ) { /* willing to create it? */
|
||||||
|
set_errno_and_return_minus_one( ENOENT );
|
||||||
|
return (mqd_t) -1;
|
||||||
|
}
|
||||||
|
/* we are willing to create it */
|
||||||
|
}
|
||||||
|
set_errno_and_return_minus_one( status ); /* some type of error */
|
||||||
|
return (mqd_t) -1;
|
||||||
|
|
||||||
|
} else { /* name -> ID translation succeeded */
|
||||||
|
|
||||||
|
if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
|
||||||
|
set_errno_and_return_minus_one( EEXIST );
|
||||||
|
return (mqd_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX In this case we need to do an ID->pointer conversion to
|
||||||
|
* check the mode. This is probably a good place for a subroutine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
the_mq->open_count += 1;
|
||||||
|
|
||||||
|
return (mqd_t)&the_mq->Object.id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX verify this comment...
|
||||||
|
*
|
||||||
|
* At this point, the message queue does not exist and everything has been
|
||||||
|
* checked. We should go ahead and create a message queue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
status = _POSIX_Message_queue_Create_support(
|
||||||
|
name,
|
||||||
|
TRUE, /* shared across processes */
|
||||||
|
oflag,
|
||||||
|
attr,
|
||||||
|
&the_mq
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( status == -1 )
|
||||||
|
return (mqd_t) -1;
|
||||||
|
|
||||||
|
return (mqd_t) &the_mq->Object.id;
|
||||||
|
}
|
||||||
|
|
||||||
53
c/src/exec/posix/src/mqueuereceive.c
Normal file
53
c/src/exec/posix/src/mqueuereceive.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
||||||
|
*/
|
||||||
|
|
||||||
|
ssize_t mq_receive(
|
||||||
|
mqd_t mqdes,
|
||||||
|
char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int *msg_prio
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Receive_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
THREAD_QUEUE_WAIT_FOREVER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
79
c/src/exec/posix/src/mqueuerecvsupp.c
Normal file
79
c/src/exec/posix/src/mqueuerecvsupp.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Receive_support
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX be careful ... watch the size going through all the layers ... */
|
||||||
|
|
||||||
|
ssize_t _POSIX_Message_queue_Receive_support(
|
||||||
|
mqd_t mqdes,
|
||||||
|
char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int *msg_prio,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
unsigned32 status = 0;
|
||||||
|
unsigned32 length_out;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/* XXX need to define the options argument to this */
|
||||||
|
length_out = msg_len;
|
||||||
|
_CORE_message_queue_Seize(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
&length_out,
|
||||||
|
/* msg_prio, XXXX */
|
||||||
|
the_mq->blocking,
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
if ( !status )
|
||||||
|
return length_out;
|
||||||
|
/* XXX --- the return codes gotta be looked at .. fix this */
|
||||||
|
return _Thread_Executing->Wait.return_code;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
53
c/src/exec/posix/src/mqueuesend.c
Normal file
53
c/src/exec/posix/src/mqueuesend.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_send(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int msg_prio
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Send_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
THREAD_QUEUE_WAIT_FOREVER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
73
c/src/exec/posix/src/mqueuesendsupp.c
Normal file
73
c/src/exec/posix/src/mqueuesendsupp.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Send_support
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Message_queue_Send_support(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const char *msg_ptr,
|
||||||
|
unsigned32 msg_len,
|
||||||
|
Priority_Control msg_prio,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/* XXX must add support for timeout and priority */
|
||||||
|
_CORE_message_queue_Send(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
(void *) msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
mqdes,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
NULL /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return _Thread_Executing->Wait.return_code;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
85
c/src/exec/posix/src/mqueuesetattr.c
Normal file
85
c/src/exec/posix/src/mqueuesetattr.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_setattr(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const struct mq_attr *mqstat,
|
||||||
|
struct mq_attr *omqstat
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
CORE_message_queue_Attributes *the_mq_attr;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/*
|
||||||
|
* Return the old values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX this is the same stuff as is in mq_getattr... and probably */
|
||||||
|
/* XXX should be in an inlined private routine */
|
||||||
|
|
||||||
|
the_mq_attr = &the_mq->Message_queue.Attributes;
|
||||||
|
|
||||||
|
omqstat->mq_flags = the_mq->flags;
|
||||||
|
omqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
||||||
|
omqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
||||||
|
omqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore everything except the O_NONBLOCK bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( mqstat->mq_flags & O_NONBLOCK )
|
||||||
|
the_mq->blocking = FALSE;
|
||||||
|
else
|
||||||
|
the_mq->blocking = TRUE;
|
||||||
|
|
||||||
|
the_mq->flags = mqstat->mq_flags;
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
54
c/src/exec/posix/src/mqueuetimedreceive.c
Normal file
54
c/src/exec/posix/src/mqueuetimedreceive.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_timedreceive( /* XXX: should this be ssize_t */
|
||||||
|
mqd_t mqdes,
|
||||||
|
char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int *msg_prio,
|
||||||
|
const struct timespec *timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Receive_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
_POSIX_Timespec_to_interval( timeout )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
54
c/src/exec/posix/src/mqueuetimedsend.c
Normal file
54
c/src/exec/posix/src/mqueuetimedsend.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_timedsend(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int msg_prio,
|
||||||
|
const struct timespec *timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Send_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
_POSIX_Timespec_to_interval( timeout )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
76
c/src/exec/posix/src/mqueueunlink.c
Normal file
76
c/src/exec/posix/src/mqueueunlink.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_unlink(
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Id the_mq_id;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
||||||
|
|
||||||
|
if ( !status )
|
||||||
|
set_errno_and_return_minus_one( status );
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( the_mq_id, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_Objects_MP_Close(
|
||||||
|
&_POSIX_Message_queue_Information,
|
||||||
|
the_mq->Object.id
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
the_mq->linked = FALSE;
|
||||||
|
|
||||||
|
_POSIX_Message_queue_Delete( the_mq );
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -55,675 +55,3 @@ void _POSIX_Message_queue_Manager_initialization(
|
|||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Create_support
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Message_queue_Create_support(
|
|
||||||
const char *name,
|
|
||||||
int pshared,
|
|
||||||
unsigned int oflag,
|
|
||||||
struct mq_attr *attr,
|
|
||||||
POSIX_Message_queue_Control **message_queue
|
|
||||||
)
|
|
||||||
{
|
|
||||||
POSIX_Message_queue_Control *the_mq;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Allocate();
|
|
||||||
|
|
||||||
if ( !the_mq ) {
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( ENFILE );
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( pshared == PTHREAD_PROCESS_SHARED &&
|
|
||||||
!( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
|
|
||||||
the_mq->Object.id, FALSE ) ) ) {
|
|
||||||
_POSIX_Message_queue_Free( the_mq );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( ENFILE );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
the_mq->process_shared = pshared;
|
|
||||||
|
|
||||||
if ( name ) {
|
|
||||||
the_mq->named = TRUE;
|
|
||||||
the_mq->open_count = 1;
|
|
||||||
the_mq->linked = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
the_mq->named = FALSE;
|
|
||||||
|
|
||||||
if ( oflag & O_NONBLOCK )
|
|
||||||
the_mq->blocking = FALSE;
|
|
||||||
else
|
|
||||||
the_mq->blocking = TRUE;
|
|
||||||
|
|
||||||
/* XXX
|
|
||||||
*
|
|
||||||
* Note that this should be based on the current scheduling policy.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX
|
|
||||||
*
|
|
||||||
* Message and waiting disciplines are not distinguished.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
the_mq_attr->message_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
|
||||||
the_mq_attr->waiting_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
|
||||||
*/
|
|
||||||
|
|
||||||
the_mq->Message_queue.Attributes.discipline =
|
|
||||||
CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
|
||||||
|
|
||||||
if ( ! _CORE_message_queue_Initialize(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
OBJECTS_POSIX_MESSAGE_QUEUES,
|
|
||||||
&the_mq->Message_queue.Attributes,
|
|
||||||
attr->mq_maxmsg,
|
|
||||||
attr->mq_msgsize,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_POSIX_Message_queue_MP_Send_extract_proxy
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
) ) {
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( pshared == PTHREAD_PROCESS_SHARED )
|
|
||||||
_Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_POSIX_Message_queue_Free( the_mq );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( ENOSPC );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* XXX - need Names to be a string!!! */
|
|
||||||
_Objects_Open(
|
|
||||||
&_POSIX_Message_queue_Information,
|
|
||||||
&the_mq->Object,
|
|
||||||
(char *) name
|
|
||||||
);
|
|
||||||
|
|
||||||
*message_queue = the_mq;
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( pshared == PTHREAD_PROCESS_SHARED )
|
|
||||||
_POSIX_Message_queue_MP_Send_process_packet(
|
|
||||||
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
|
|
||||||
the_mq->Object.id,
|
|
||||||
(char *) name,
|
|
||||||
0 /* Not used */
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
|
|
||||||
*/
|
|
||||||
|
|
||||||
mqd_t mq_open(
|
|
||||||
const char *name,
|
|
||||||
int oflag,
|
|
||||||
...
|
|
||||||
/* mode_t mode, */
|
|
||||||
/* struct mq_attr attr */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
va_list arg;
|
|
||||||
mode_t mode;
|
|
||||||
struct mq_attr *attr;
|
|
||||||
int status;
|
|
||||||
Objects_Id the_mq_id;
|
|
||||||
POSIX_Message_queue_Control *the_mq;
|
|
||||||
|
|
||||||
if ( oflag & O_CREAT ) {
|
|
||||||
va_start(arg, oflag);
|
|
||||||
mode = (mode_t) va_arg( arg, mode_t * );
|
|
||||||
attr = (struct mq_attr *) va_arg( arg, struct mq_attr ** );
|
|
||||||
va_end(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the name to id translation worked, then the message queue exists
|
|
||||||
* and we can just return a pointer to the id. Otherwise we may
|
|
||||||
* need to check to see if this is a "message queue does not exist"
|
|
||||||
* or some other miscellaneous error on the name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( status ) {
|
|
||||||
|
|
||||||
if ( status == EINVAL ) { /* name -> ID translation failed */
|
|
||||||
if ( !(oflag & O_CREAT) ) { /* willing to create it? */
|
|
||||||
set_errno_and_return_minus_one( ENOENT );
|
|
||||||
return (mqd_t) -1;
|
|
||||||
}
|
|
||||||
/* we are willing to create it */
|
|
||||||
}
|
|
||||||
set_errno_and_return_minus_one( status ); /* some type of error */
|
|
||||||
return (mqd_t) -1;
|
|
||||||
|
|
||||||
} else { /* name -> ID translation succeeded */
|
|
||||||
|
|
||||||
if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
|
|
||||||
set_errno_and_return_minus_one( EEXIST );
|
|
||||||
return (mqd_t) -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX In this case we need to do an ID->pointer conversion to
|
|
||||||
* check the mode. This is probably a good place for a subroutine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
the_mq->open_count += 1;
|
|
||||||
|
|
||||||
return (mqd_t)&the_mq->Object.id;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX verify this comment...
|
|
||||||
*
|
|
||||||
* At this point, the message queue does not exist and everything has been
|
|
||||||
* checked. We should go ahead and create a message queue.
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = _POSIX_Message_queue_Create_support(
|
|
||||||
name,
|
|
||||||
TRUE, /* shared across processes */
|
|
||||||
oflag,
|
|
||||||
attr,
|
|
||||||
&the_mq
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( status == -1 )
|
|
||||||
return (mqd_t) -1;
|
|
||||||
|
|
||||||
return (mqd_t) &the_mq->Object.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Delete
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _POSIX_Message_queue_Delete(
|
|
||||||
POSIX_Message_queue_Control *the_mq
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !the_mq->linked && !the_mq->open_count ) {
|
|
||||||
_POSIX_Message_queue_Free( the_mq );
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
|
|
||||||
|
|
||||||
_Objects_MP_Close(
|
|
||||||
&_POSIX_Message_queue_Information,
|
|
||||||
the_mq->Object.id
|
|
||||||
);
|
|
||||||
|
|
||||||
_POSIX_Message_queue_MP_Send_process_packet(
|
|
||||||
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
|
|
||||||
the_mq->Object.id,
|
|
||||||
0, /* Not used */
|
|
||||||
0 /* Not used */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_close(
|
|
||||||
mqd_t mqdes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
the_mq->open_count -= 1;
|
|
||||||
_POSIX_Message_queue_Delete( the_mq );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_unlink(
|
|
||||||
const char *name
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Id the_mq_id;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
|
||||||
|
|
||||||
if ( !status )
|
|
||||||
set_errno_and_return_minus_one( status );
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( the_mq_id, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_Objects_MP_Close(
|
|
||||||
&_POSIX_Message_queue_Information,
|
|
||||||
the_mq->Object.id
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
the_mq->linked = FALSE;
|
|
||||||
|
|
||||||
_POSIX_Message_queue_Delete( the_mq );
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Send_support
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Message_queue_Send_support(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const char *msg_ptr,
|
|
||||||
unsigned32 msg_len,
|
|
||||||
Priority_Control msg_prio,
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/* XXX must add support for timeout and priority */
|
|
||||||
_CORE_message_queue_Send(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
(void *) msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
mqdes,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
NULL /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return _Thread_Executing->Wait.return_code;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_send(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int msg_prio
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Send_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_timedsend(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int msg_prio,
|
|
||||||
const struct timespec *timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Send_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Receive_support
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX be careful ... watch the size going through all the layers ... */
|
|
||||||
|
|
||||||
ssize_t _POSIX_Message_queue_Receive_support(
|
|
||||||
mqd_t mqdes,
|
|
||||||
char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int *msg_prio,
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
unsigned32 status = 0;
|
|
||||||
unsigned32 length_out;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/* XXX need to define the options argument to this */
|
|
||||||
length_out = msg_len;
|
|
||||||
_CORE_message_queue_Seize(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
&length_out,
|
|
||||||
/* msg_prio, XXXX */
|
|
||||||
the_mq->blocking,
|
|
||||||
timeout
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
if ( !status )
|
|
||||||
return length_out;
|
|
||||||
/* XXX --- the return codes gotta be looked at .. fix this */
|
|
||||||
return _Thread_Executing->Wait.return_code;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
|
||||||
*/
|
|
||||||
|
|
||||||
ssize_t mq_receive(
|
|
||||||
mqd_t mqdes,
|
|
||||||
char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int *msg_prio
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Receive_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_timedreceive( /* XXX: should this be ssize_t */
|
|
||||||
mqd_t mqdes,
|
|
||||||
char *msg_ptr,
|
|
||||||
size_t msg_len,
|
|
||||||
unsigned int *msg_prio,
|
|
||||||
const struct timespec *timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Message_queue_Receive_support(
|
|
||||||
mqdes,
|
|
||||||
msg_ptr,
|
|
||||||
msg_len,
|
|
||||||
msg_prio,
|
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Notify_handler
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _POSIX_Message_queue_Notify_handler(
|
|
||||||
void *user_data
|
|
||||||
)
|
|
||||||
{
|
|
||||||
POSIX_Message_queue_Control *the_mq;
|
|
||||||
|
|
||||||
the_mq = user_data;
|
|
||||||
|
|
||||||
/* XXX do something with signals here!!!! */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.6 Notify Process that a Message is Available on a Queue,
|
|
||||||
* P1003.1b-1993, p. 280
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_notify(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const struct sigevent *notification
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EBADF );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
if ( notification ) {
|
|
||||||
if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
set_errno_and_return_minus_one( EBUSY );
|
|
||||||
}
|
|
||||||
|
|
||||||
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
|
||||||
|
|
||||||
the_mq->notification = *notification;
|
|
||||||
|
|
||||||
_CORE_message_queue_Set_notify(
|
|
||||||
&the_mq->Message_queue,
|
|
||||||
_POSIX_Message_queue_Notify_handler,
|
|
||||||
the_mq
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_setattr(
|
|
||||||
mqd_t mqdes,
|
|
||||||
const struct mq_attr *mqstat,
|
|
||||||
struct mq_attr *omqstat
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
CORE_message_queue_Attributes *the_mq_attr;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/*
|
|
||||||
* Return the old values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX this is the same stuff as is in mq_getattr... and probably */
|
|
||||||
/* XXX should be in an inlined private routine */
|
|
||||||
|
|
||||||
the_mq_attr = &the_mq->Message_queue.Attributes;
|
|
||||||
|
|
||||||
omqstat->mq_flags = the_mq->flags;
|
|
||||||
omqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
|
||||||
omqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
|
||||||
omqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ignore everything except the O_NONBLOCK bit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( mqstat->mq_flags & O_NONBLOCK )
|
|
||||||
the_mq->blocking = FALSE;
|
|
||||||
else
|
|
||||||
the_mq->blocking = TRUE;
|
|
||||||
|
|
||||||
the_mq->flags = mqstat->mq_flags;
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
|
|
||||||
*/
|
|
||||||
|
|
||||||
int mq_getattr(
|
|
||||||
mqd_t mqdes,
|
|
||||||
struct mq_attr *mqstat
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Message_queue_Control *the_mq;
|
|
||||||
Objects_Locations location;
|
|
||||||
CORE_message_queue_Attributes *the_mq_attr;
|
|
||||||
|
|
||||||
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
set_errno_and_return_minus_one( EINVAL );
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/*
|
|
||||||
* Return the old values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX this is the same stuff as is in mq_setattr... and probably */
|
|
||||||
/* XXX should be in an inlined private routine */
|
|
||||||
|
|
||||||
the_mq_attr = &the_mq->Message_queue.Attributes;
|
|
||||||
|
|
||||||
mqstat->mq_flags = the_mq->flags;
|
|
||||||
mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
|
||||||
mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
|
||||||
mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
|
||||||
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Name_to_id
|
|
||||||
*
|
|
||||||
* XXX
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Message_queue_Name_to_id(
|
|
||||||
const char *name,
|
|
||||||
Objects_Id *id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return 0; /* XXX fill me in */
|
|
||||||
}
|
|
||||||
|
|||||||
58
cpukit/posix/src/mqueueclose.c
Normal file
58
cpukit/posix/src/mqueueclose.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_close(
|
||||||
|
mqd_t mqdes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
the_mq->open_count -= 1;
|
||||||
|
_POSIX_Message_queue_Delete( the_mq );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
143
cpukit/posix/src/mqueuecreatesupp.c
Normal file
143
cpukit/posix/src/mqueuecreatesupp.c
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Create_support
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Message_queue_Create_support(
|
||||||
|
const char *name,
|
||||||
|
int pshared,
|
||||||
|
unsigned int oflag,
|
||||||
|
struct mq_attr *attr,
|
||||||
|
POSIX_Message_queue_Control **message_queue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
POSIX_Message_queue_Control *the_mq;
|
||||||
|
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Allocate();
|
||||||
|
|
||||||
|
if ( !the_mq ) {
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( ENFILE );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( pshared == PTHREAD_PROCESS_SHARED &&
|
||||||
|
!( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
|
||||||
|
the_mq->Object.id, FALSE ) ) ) {
|
||||||
|
_POSIX_Message_queue_Free( the_mq );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( ENFILE );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
the_mq->process_shared = pshared;
|
||||||
|
|
||||||
|
if ( name ) {
|
||||||
|
the_mq->named = TRUE;
|
||||||
|
the_mq->open_count = 1;
|
||||||
|
the_mq->linked = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
the_mq->named = FALSE;
|
||||||
|
|
||||||
|
if ( oflag & O_NONBLOCK )
|
||||||
|
the_mq->blocking = FALSE;
|
||||||
|
else
|
||||||
|
the_mq->blocking = TRUE;
|
||||||
|
|
||||||
|
/* XXX
|
||||||
|
*
|
||||||
|
* Note that this should be based on the current scheduling policy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX
|
||||||
|
*
|
||||||
|
* Message and waiting disciplines are not distinguished.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
the_mq_attr->message_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||||
|
the_mq_attr->waiting_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||||
|
*/
|
||||||
|
|
||||||
|
the_mq->Message_queue.Attributes.discipline =
|
||||||
|
CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
|
||||||
|
|
||||||
|
if ( ! _CORE_message_queue_Initialize(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
OBJECTS_POSIX_MESSAGE_QUEUES,
|
||||||
|
&the_mq->Message_queue.Attributes,
|
||||||
|
attr->mq_maxmsg,
|
||||||
|
attr->mq_msgsize,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_POSIX_Message_queue_MP_Send_extract_proxy
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
) ) {
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( pshared == PTHREAD_PROCESS_SHARED )
|
||||||
|
_Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_POSIX_Message_queue_Free( the_mq );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( ENOSPC );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX - need Names to be a string!!! */
|
||||||
|
_Objects_Open(
|
||||||
|
&_POSIX_Message_queue_Information,
|
||||||
|
&the_mq->Object,
|
||||||
|
(char *) name
|
||||||
|
);
|
||||||
|
|
||||||
|
*message_queue = the_mq;
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( pshared == PTHREAD_PROCESS_SHARED )
|
||||||
|
_POSIX_Message_queue_MP_Send_process_packet(
|
||||||
|
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
|
||||||
|
the_mq->Object.id,
|
||||||
|
(char *) name,
|
||||||
|
0 /* Not used */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
62
cpukit/posix/src/mqueuedeletesupp.c
Normal file
62
cpukit/posix/src/mqueuedeletesupp.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Delete
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _POSIX_Message_queue_Delete(
|
||||||
|
POSIX_Message_queue_Control *the_mq
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !the_mq->linked && !the_mq->open_count ) {
|
||||||
|
_POSIX_Message_queue_Free( the_mq );
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
|
||||||
|
|
||||||
|
_Objects_MP_Close(
|
||||||
|
&_POSIX_Message_queue_Information,
|
||||||
|
the_mq->Object.id
|
||||||
|
);
|
||||||
|
|
||||||
|
_POSIX_Message_queue_MP_Send_process_packet(
|
||||||
|
POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
|
||||||
|
the_mq->Object.id,
|
||||||
|
0, /* Not used */
|
||||||
|
0 /* Not used */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
73
cpukit/posix/src/mqueuegetattr.c
Normal file
73
cpukit/posix/src/mqueuegetattr.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_getattr(
|
||||||
|
mqd_t mqdes,
|
||||||
|
struct mq_attr *mqstat
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
CORE_message_queue_Attributes *the_mq_attr;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/*
|
||||||
|
* Return the old values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX this is the same stuff as is in mq_setattr... and probably */
|
||||||
|
/* XXX should be in an inlined private routine */
|
||||||
|
|
||||||
|
the_mq_attr = &the_mq->Message_queue.Attributes;
|
||||||
|
|
||||||
|
mqstat->mq_flags = the_mq->flags;
|
||||||
|
mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
||||||
|
mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
||||||
|
mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
44
cpukit/posix/src/mqueuenametoid.c
Normal file
44
cpukit/posix/src/mqueuenametoid.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Name_to_id
|
||||||
|
*
|
||||||
|
* XXX
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Message_queue_Name_to_id(
|
||||||
|
const char *name,
|
||||||
|
Objects_Id *id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 0; /* XXX fill me in */
|
||||||
|
}
|
||||||
97
cpukit/posix/src/mqueuenotify.c
Normal file
97
cpukit/posix/src/mqueuenotify.c
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Notify_handler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _POSIX_Message_queue_Notify_handler(
|
||||||
|
void *user_data
|
||||||
|
)
|
||||||
|
{
|
||||||
|
POSIX_Message_queue_Control *the_mq;
|
||||||
|
|
||||||
|
the_mq = user_data;
|
||||||
|
|
||||||
|
/* XXX do something with signals here!!!! */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.6 Notify Process that a Message is Available on a Queue,
|
||||||
|
* P1003.1b-1993, p. 280
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_notify(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const struct sigevent *notification
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EBADF );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
if ( notification ) {
|
||||||
|
if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
set_errno_and_return_minus_one( EBUSY );
|
||||||
|
}
|
||||||
|
|
||||||
|
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
||||||
|
|
||||||
|
the_mq->notification = *notification;
|
||||||
|
|
||||||
|
_CORE_message_queue_Set_notify(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
_POSIX_Message_queue_Notify_handler,
|
||||||
|
the_mq
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
_CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
116
cpukit/posix/src/mqueueopen.c
Normal file
116
cpukit/posix/src/mqueueopen.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
|
||||||
|
*/
|
||||||
|
|
||||||
|
mqd_t mq_open(
|
||||||
|
const char *name,
|
||||||
|
int oflag,
|
||||||
|
...
|
||||||
|
/* mode_t mode, */
|
||||||
|
/* struct mq_attr attr */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
mode_t mode;
|
||||||
|
struct mq_attr *attr;
|
||||||
|
int status;
|
||||||
|
Objects_Id the_mq_id;
|
||||||
|
POSIX_Message_queue_Control *the_mq;
|
||||||
|
|
||||||
|
if ( oflag & O_CREAT ) {
|
||||||
|
va_start(arg, oflag);
|
||||||
|
mode = (mode_t) va_arg( arg, mode_t );
|
||||||
|
attr = (struct mq_attr *) va_arg( arg, struct mq_attr * );
|
||||||
|
va_end(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the name to id translation worked, then the message queue exists
|
||||||
|
* and we can just return a pointer to the id. Otherwise we may
|
||||||
|
* need to check to see if this is a "message queue does not exist"
|
||||||
|
* or some other miscellaneous error on the name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( status ) {
|
||||||
|
|
||||||
|
if ( status == EINVAL ) { /* name -> ID translation failed */
|
||||||
|
if ( !(oflag & O_CREAT) ) { /* willing to create it? */
|
||||||
|
set_errno_and_return_minus_one( ENOENT );
|
||||||
|
return (mqd_t) -1;
|
||||||
|
}
|
||||||
|
/* we are willing to create it */
|
||||||
|
}
|
||||||
|
set_errno_and_return_minus_one( status ); /* some type of error */
|
||||||
|
return (mqd_t) -1;
|
||||||
|
|
||||||
|
} else { /* name -> ID translation succeeded */
|
||||||
|
|
||||||
|
if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
|
||||||
|
set_errno_and_return_minus_one( EEXIST );
|
||||||
|
return (mqd_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX In this case we need to do an ID->pointer conversion to
|
||||||
|
* check the mode. This is probably a good place for a subroutine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
the_mq->open_count += 1;
|
||||||
|
|
||||||
|
return (mqd_t)&the_mq->Object.id;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX verify this comment...
|
||||||
|
*
|
||||||
|
* At this point, the message queue does not exist and everything has been
|
||||||
|
* checked. We should go ahead and create a message queue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
status = _POSIX_Message_queue_Create_support(
|
||||||
|
name,
|
||||||
|
TRUE, /* shared across processes */
|
||||||
|
oflag,
|
||||||
|
attr,
|
||||||
|
&the_mq
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( status == -1 )
|
||||||
|
return (mqd_t) -1;
|
||||||
|
|
||||||
|
return (mqd_t) &the_mq->Object.id;
|
||||||
|
}
|
||||||
|
|
||||||
53
cpukit/posix/src/mqueuereceive.c
Normal file
53
cpukit/posix/src/mqueuereceive.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
||||||
|
*/
|
||||||
|
|
||||||
|
ssize_t mq_receive(
|
||||||
|
mqd_t mqdes,
|
||||||
|
char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int *msg_prio
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Receive_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
THREAD_QUEUE_WAIT_FOREVER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
79
cpukit/posix/src/mqueuerecvsupp.c
Normal file
79
cpukit/posix/src/mqueuerecvsupp.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Receive_support
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX be careful ... watch the size going through all the layers ... */
|
||||||
|
|
||||||
|
ssize_t _POSIX_Message_queue_Receive_support(
|
||||||
|
mqd_t mqdes,
|
||||||
|
char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int *msg_prio,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
unsigned32 status = 0;
|
||||||
|
unsigned32 length_out;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/* XXX need to define the options argument to this */
|
||||||
|
length_out = msg_len;
|
||||||
|
_CORE_message_queue_Seize(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
&length_out,
|
||||||
|
/* msg_prio, XXXX */
|
||||||
|
the_mq->blocking,
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
if ( !status )
|
||||||
|
return length_out;
|
||||||
|
/* XXX --- the return codes gotta be looked at .. fix this */
|
||||||
|
return _Thread_Executing->Wait.return_code;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
53
cpukit/posix/src/mqueuesend.c
Normal file
53
cpukit/posix/src/mqueuesend.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_send(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int msg_prio
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Send_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
THREAD_QUEUE_WAIT_FOREVER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
73
cpukit/posix/src/mqueuesendsupp.c
Normal file
73
cpukit/posix/src/mqueuesendsupp.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Message_queue_Send_support
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Message_queue_Send_support(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const char *msg_ptr,
|
||||||
|
unsigned32 msg_len,
|
||||||
|
Priority_Control msg_prio,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/* XXX must add support for timeout and priority */
|
||||||
|
_CORE_message_queue_Send(
|
||||||
|
&the_mq->Message_queue,
|
||||||
|
(void *) msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
mqdes,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
NULL /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return _Thread_Executing->Wait.return_code;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
85
cpukit/posix/src/mqueuesetattr.c
Normal file
85
cpukit/posix/src/mqueuesetattr.c
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_setattr(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const struct mq_attr *mqstat,
|
||||||
|
struct mq_attr *omqstat
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Locations location;
|
||||||
|
CORE_message_queue_Attributes *the_mq_attr;
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( mqdes, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/*
|
||||||
|
* Return the old values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX this is the same stuff as is in mq_getattr... and probably */
|
||||||
|
/* XXX should be in an inlined private routine */
|
||||||
|
|
||||||
|
the_mq_attr = &the_mq->Message_queue.Attributes;
|
||||||
|
|
||||||
|
omqstat->mq_flags = the_mq->flags;
|
||||||
|
omqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
|
||||||
|
omqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
|
||||||
|
omqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore everything except the O_NONBLOCK bit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( mqstat->mq_flags & O_NONBLOCK )
|
||||||
|
the_mq->blocking = FALSE;
|
||||||
|
else
|
||||||
|
the_mq->blocking = TRUE;
|
||||||
|
|
||||||
|
the_mq->flags = mqstat->mq_flags;
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
54
cpukit/posix/src/mqueuetimedreceive.c
Normal file
54
cpukit/posix/src/mqueuetimedreceive.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_timedreceive( /* XXX: should this be ssize_t */
|
||||||
|
mqd_t mqdes,
|
||||||
|
char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int *msg_prio,
|
||||||
|
const struct timespec *timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Receive_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
_POSIX_Timespec_to_interval( timeout )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
54
cpukit/posix/src/mqueuetimedsend.c
Normal file
54
cpukit/posix/src/mqueuetimedsend.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_timedsend(
|
||||||
|
mqd_t mqdes,
|
||||||
|
const char *msg_ptr,
|
||||||
|
size_t msg_len,
|
||||||
|
unsigned int msg_prio,
|
||||||
|
const struct timespec *timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Message_queue_Send_support(
|
||||||
|
mqdes,
|
||||||
|
msg_ptr,
|
||||||
|
msg_len,
|
||||||
|
msg_prio,
|
||||||
|
_POSIX_Timespec_to_interval( timeout )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
76
cpukit/posix/src/mqueueunlink.c
Normal file
76
cpukit/posix/src/mqueueunlink.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* NOTE: The structure of the routines is identical to that of POSIX
|
||||||
|
* Message_queues to leave the option of having unnamed message
|
||||||
|
* queues at a future date. They are currently not part of the
|
||||||
|
* POSIX standard but unnamed message_queues are. This is also
|
||||||
|
* the reason for the apparently unnecessary tracking of
|
||||||
|
* the process_shared attribute. [In addition to the fact that
|
||||||
|
* it would be trivial to add pshared to the mq_attr structure
|
||||||
|
* and have process private message queues.]
|
||||||
|
*
|
||||||
|
* This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#include <rtems/posix/seterr.h>
|
||||||
|
#include <rtems/posix/mqueue.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mq_unlink(
|
||||||
|
const char *name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
register POSIX_Message_queue_Control *the_mq;
|
||||||
|
Objects_Id the_mq_id;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
|
||||||
|
|
||||||
|
if ( !status )
|
||||||
|
set_errno_and_return_minus_one( status );
|
||||||
|
|
||||||
|
the_mq = _POSIX_Message_queue_Get( the_mq_id, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
set_errno_and_return_minus_one( EINVAL );
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_Objects_MP_Close(
|
||||||
|
&_POSIX_Message_queue_Information,
|
||||||
|
the_mq->Object.id
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
the_mq->linked = FALSE;
|
||||||
|
|
||||||
|
_POSIX_Message_queue_Delete( the_mq );
|
||||||
|
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user