mq_open()
Open a message queue
Synopsis:
#include <mqueue.h>
#include <fcntl.h>
mqd_t mq_open( const char * name,
int oflag,
... )
Arguments:
- name
- The name of the message queue that you want to open; see below.
- oflag
- You must specify one of O_RDONLY (receive-only), O_WRONLY
(send-only), or O_RDWR (send-receive). In addition, you can OR in the
following constants to produce the following effects:
- O_CREAT — if name doesn't exist, instruct the server to create a new message queue with the given name. If you specify this flag, mq_open() uses its mode and mq_attr arguments; see below.
- O_EXCL — if you set both O_EXCL and O_CREAT, and a message queue name exists, the call fails and errno is set to EEXIST. Otherwise, the queue is created normally. If you set O_EXCL without O_CREAT, it's ignored.
- O_NONBLOCK — under normal message queue operation, a call to mq_send() or mq_receive() could block if the message queue is full or empty. If you set this flag, these calls never block. If the queue isn't in a condition to perform the given call, errno is set to EAGAIN and the call returns an error.
If you set O_CREAT in the oflag argument, you must also pass these arguments to mq_open():
- mode_t mode
- The file permissions for the new queue. For more information, see the
st_mode
field description for struct stat.
If you set any bits other than file permission bits, they're ignored. Read and write permissions are analogous to receive and send permissions; execute permissions are ignored.
- struct mq_attr *mq_attr
- NULL, or a pointer to an mq_attr structure that contains the
attributes that you want to use for the new queue. For more information, see mq_getattr().
If mq_attr is NULL, the following default attributes are used:
Attribute Default mq_maxmsg 1024 mq_msgsize 4096 mq_flags 0 If mq_attr isn't NULL, the new queue uses the mq_maxmsg and mq_msgsize defined in this structure. The mq_flags field is ignored.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The mq_open() function opens a message queue referred to by name, and returns a message queue descriptor by which the queue can be referenced in the future.
The mq_open() function creates an entry for the message queue in the pathname space under the /dev/mqueue directory.
The name argument is interpreted as follows:
- If the name argument starts with a slash, the queue is given that name.
- If the name argument doesn't begin with a slash character, the queue is given that name, prepended with the current working directory.
In either case, slash characters other than the leading slash character aren't interpreted, and the specified name, including these slash characters, is used to identify the message queue. In other words, additional slashes don't create a directory structure under /dev/mqueue.
For example, if your current directory is /tmp:
name | Resulting pathname |
---|---|
/entry |
/dev/mqueue/entry |
entry |
/dev/mqueue/tmp/entry |
Returns:
A valid message queue descriptor if the queue is successfully created, or -1 (errno is set).
Errors:
- EACCES
- The message queue exists, and you don't have permission to open the queue under the given oflag, or the message queue doesn't exist, and you don't have permission to create one.
- EEXIST
- You specified the O_CREAT and O_EXCL flags in oflag, and the queue name exists.
- EINTR
- The operation was interrupted by a signal.
- EINVAL
- You specified the O_CREAT flag in oflag, and mq_attr wasn't NULL, but some values in the mq_attr structure were invalid.
- ELOOP
- Too many levels of symbolic links or prefixes.
- EMFILE
- Too many message queue descriptors or file descriptors are in use by the calling process.
- ENAMETOOLONG
- The length of name exceeds PATH_MAX.
- ENFILE
- Too many message queues are open in the system.
- ENOENT
- You didn't set the O_CREAT flag, and the queue name doesn't exist.
- ENOSPC
- The message queue server has run out of memory.
- EPERM
- The process doesn't have the necessary ability to connect (PROCMGR_AID_CHANNEL_CONNECT).
- ENOSYS
- The message queue manager (mqueue) isn't running.
Examples:
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#define MAX_MSG_SIZE 4096
#define MAX_MSGS 2
int main( void )
{
mqd_t msg_queue;
int ret, i;
int msg_num = 0;
unsigned int prio;
char send_msg[MAX_MSG_SIZE];
char received_msg[MAX_MSG_SIZE];
ssize_t received_len;
struct timespec abs_timeout;
struct mq_attr attrs;
/* Open a message queue. We'll restrict the number of messages so that the
queue fills up quickly. */
memset(&attrs, 0, sizeof attrs);
attrs.mq_maxmsg = MAX_MSGS;
attrs.mq_msgsize = MAX_MSG_SIZE;
msg_queue = mq_open( "/my_queue", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, &attrs );
if (msg_queue == -1) {
perror ("mq_open()");
return EXIT_FAILURE;
}
printf ("Successfully opened my_queue:\n");
/* Get the queue's attributes. */
ret = mq_getattr (msg_queue, &attrs);
if (ret == -1) {
perror ("mq_getattr()");
return EXIT_FAILURE;
}
printf (" Flags: %lx; max messages: %ld; max message size: %ld\n",
attrs.mq_flags, attrs.mq_maxmsg, attrs.mq_msgsize);
printf (" Messages: %ld; send waits: %ld; receive waits: %ld\n\n",
attrs.mq_curmsgs, attrs.mq_sendwait, attrs.mq_recvwait);
/* Send enough messages to fill the queue. */
for (i=1; i <= MAX_MSGS; i++)
{
msg_num++;
sprintf (send_msg, "This is message number %d.", msg_num);
ret = mq_send (msg_queue, send_msg, sizeof(send_msg), 5);
if (ret == -1) {
perror ("mq_send()");
return EXIT_FAILURE;
}
ret = mq_getattr (msg_queue, &attrs);
if (ret == -1) {
perror ("mq_getattr()");
return EXIT_FAILURE;
}
printf ("After sending:\n");
printf (" Messages: %ld; send waits: %ld; receive waits: %ld\n\n",
attrs.mq_curmsgs, attrs.mq_sendwait, attrs.mq_recvwait);
}
/* Send a message, specifying a time limit. This should time out
because the queue is full. */
clock_gettime(CLOCK_REALTIME, &abs_timeout);
abs_timeout.tv_sec += 1;
msg_num++;
sprintf (send_msg, "This is message number %d.", msg_num);
ret = mq_timedsend (msg_queue, send_msg, sizeof(send_msg), 5, &abs_timeout);
if (ret == -1) {
if (errno == ETIMEDOUT) {
printf ("mq_timedsend() timed out:\n");
} else {
perror ("mq_timedsend()");
return EXIT_FAILURE;
}
} else {
printf ("After sending with a time limit:\n");
}
ret = mq_getattr (msg_queue, &attrs);
if (ret == -1) {
perror ("mq_getattr()");
return EXIT_FAILURE;
}
printf (" Messages: %ld; send waits: %ld; receive waits: %ld\n\n",
attrs.mq_curmsgs, attrs.mq_sendwait, attrs.mq_recvwait);
/* Receive enough messages to empty the queue. */
for (i=1; i <= MAX_MSGS; i++)
{
received_len = mq_receive (msg_queue, received_msg, MAX_MSG_SIZE, &prio);
if (received_len == -1) {
perror ("mq_receive()");
return EXIT_FAILURE;
}
printf ("After receiving:\n");
printf (" Length: %ld; priority: %d; msg: \"%s\"\n", received_len, prio, received_msg);
ret = mq_getattr (msg_queue, &attrs);
if (ret == -1) {
perror ("mq_getattr()");
return EXIT_FAILURE;
}
printf (" Messages: %ld; send waits: %ld; receive waits: %ld\n\n",
attrs.mq_curmsgs, attrs.mq_sendwait, attrs.mq_recvwait);
}
/* Receive a message, specifying a time limit. This should time out
because the queue is now empty. */
clock_gettime(CLOCK_REALTIME, &abs_timeout);
abs_timeout.tv_sec += 1;
received_len = mq_timedreceive (msg_queue, received_msg, MAX_MSG_SIZE, &prio,
&abs_timeout);
if (received_len == -1) {
if (errno == ETIMEDOUT) {
printf ("mq_timedreceive() timed out:\n");
} else {
perror ("mq_timedreceive()");
return EXIT_FAILURE;
}
} else {
printf ("After receiving, specifying a time limit:\n");
printf (" Length: %ld; priority: %d; msg: \"%s\"\n", received_len, prio, received_msg);
}
ret = mq_getattr (msg_queue, &attrs);
if (ret == -1) {
perror ("mq_getattr()");
return EXIT_FAILURE;
}
printf (" Messages: %ld; send waits: %ld; receive waits: %ld\n",
attrs.mq_curmsgs, attrs.mq_sendwait, attrs.mq_recvwait);
/* Unlink and then close the message queue. */
ret = mq_unlink ("/my_queue");
if (ret == -1) {
perror ("mq_unlink()");
return EXIT_FAILURE;
}
ret = mq_close (msg_queue);
if (ret == -1) {
perror ("mq_close()");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Classification:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | No |
Thread | Yes |