Updated: April 19, 2023 |
Open a message queue
#include <mqueue.h> #include <fcntl.h> mqd_t mq_open( const char * name, int oflag, ... )
If you set O_CREAT in the oflag argument, you must also pass these arguments to mq_open():
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.
If mq_attr is NULL, the following default attributes are used—depending on which implementation of message queues you're using—provided that you didn't override the defaults when you started the message-queue server:
Attribute | Traditional | Alternate |
---|---|---|
mq_maxmsg | 1024 | 64 |
mq_msgsize | 4096 | 256 |
mq_flags | 0 | 0 |
If mq_attr isn't NULL, the new queue adopts the mq_maxmsg and mq_msgsize of mq_attr. The mq_flags flags field is ignored.
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:
The name argument is interpreted as follows:
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 or /dev/mq.
For example, if your current directory is /tmp:
name | Entry with mqueue | Entry with mq |
---|---|---|
/entry | /dev/mqueue/entry | /dev/mq/entry |
entry | /dev/mqueue/tmp/entry | /dev/mq/tmp/entry |
If you want to open a queue on another node, you have to use the traditional (mqueue) implementation and specify the name as /net/node/mqueue_location. Here, node is the node name and mqeueue_location is the device entry for the queue under /dev/mqueue (on the remote node). For instance, if you want to open the queue at /dev/mqueue/mylocalqueue on a node named NTO1, you must use the name /net/NTO1/mylocalqueue in calling mq_open().
Note the difference in the path syntax required for QNX SDP 7.0 as compared to earlier releases (i.e., 6.X). In this later release, you must not include /dev/mqueue in the path of the message queue.
If name doesn't exist, mq_open() examines the third and fourth parameters: a mode_t and a pointer to an mq_attr structure.
The only time that a call to mq_open() with O_CREAT set fails is if you had opened a message queue (with the same name) and later unlinked it, but never closed it. Like their file counterparts, an unlinked queue that hasn't yet been closed must continue to exist; an attempt to recreate such a message queue fails, and errno is set to ENOENT.
A valid message queue descriptor if the queue is successfully created, or -1 (errno is set).
#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; }
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | No |
Thread | Yes |