mq_open(3)

๐Ÿ’– mq_open(3) โ€” the manual page, bestie edition ๐Ÿ’–

okay so like. this is mq_open(3) from the Library Functions Manual, and it's genuinely one of the most useful little guys in the real-time library. sit down, grab a strawberry ๐Ÿ“, we're doing message queues.

โœจ NAME โœจ

mq_open โ€” open a message queue. that's it, that's the whole vibe check. ๐Ÿ’…

๐Ÿ“š LIBRARY ๐Ÿ“š

Real-time library โ€” that's librt, so you link with -lrt. don't forget it or the linker will literally ghost you. ๐Ÿ˜ญ

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <mqueue.h>

mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode,
              struct mq_attr *attr);

two whole forms. pick your fighter. โœจ

๐ŸŒธ DESCRIPTION ๐ŸŒธ

mq_open() either creates a brand new POSIX message queue or opens one that already exists. the queue is identified by name. and bestie, if you wanna know how name is supposed to be constructed, go read mq_overview(7) โ€” that's the lore, i'm not repeating it here. ๐Ÿฆ‹

the oflag argument is the flags that control how this call behaves. (you get the flag definitions by including <fcntl.h>.) exactly one of these three must be in oflag โ€” not zero, not two, exactly one, no cap:

  • O_RDONLY โ€” open the queue to receive messages only. read-only girlie.
  • O_WRONLY โ€” open the queue to send messages only. sending era.
  • O_RDWR โ€” open the queue to both send and receive. main character energy, do it all. ๐Ÿ‘‘

and then zero or more of these can additionally be ORed into oflag:

  • O_CLOEXEC (since Linux 2.6.26) โ€” sets the close-on-exec flag for the message queue descriptor. if you're wondering why that flag is such a big deal, open(2) has the whole discussion, go look. ๐Ÿ”ฅ
  • O_CREAT โ€” create the message queue if it doesn't already exist. the owner (user ID) of the queue gets set to the effective user ID of the calling process, and the group ownership (group ID) gets set to the effective group ID of the calling process. so it's yours now, congrats. ๐Ÿ’–
  • O_EXCL โ€” so if O_CREAT was also in oflag, and a queue with that name already exists, it fails with the error EEXIST. no duplicates, periodt.
  • O_NONBLOCK โ€” open the queue in nonblocking mode. in the situations where mq_receive(3) and mq_send(3) would normally just sit there and block, they instead fail with the error EAGAIN. anti-waiting technology. ๐Ÿ’€

now the important part: if O_CREAT is in oflag, you have to supply two extra arguments. ๐Ÿ‘€

the mode argument is the permissions to put on the new queue โ€” works just like open(2). (you get the symbolic definitions for the permission bits by including <sys/stat.h>.) and heads up: those permissions get masked against the process umask.

the fields of the struct mq_attr that attr points to specify the maximum number of messages and the maximum size of messages that the queue will allow. here's the whole struct, verbatim, look how cute it is:

struct mq_attr {
    long mq_flags;       /* Flags (ignored for mq_open()) */
    long mq_maxmsg;      /* Max. # of messages on queue */
    long mq_msgsize;     /* Max. message size (bytes) */
    long mq_curmsgs;     /* # of messages currently in queue
                            (ignored for mq_open()) */
};

so when you call mq_open(), only mq_maxmsg and mq_msgsize are employed. the values in the other fields get ignored โ€” they're just there vibing. ๐Ÿ™ˆ

if attr is NULL, the queue gets created with implementation-defined default attributes. and since Linux 3.5 there are two /proc files you can use to control those defaults โ€” mq_overview(7) has the details. slay.

๐Ÿซถ RETURN VALUE ๐Ÿซถ

on success, mq_open() returns a message queue descriptor for use by the other message queue functions. iconic.

on error, it returns (mqd_t) -1, and errno gets set to indicate the error. ๐Ÿ˜ญ

๐Ÿ’€ ERRORS ๐Ÿ’€

  • EACCES โ€” the queue exists, but the caller doesn't have permission to open it in the specified mode.
  • EACCES โ€” name contained more than one slash. one slash max, bestie.
  • EEXIST โ€” both O_CREAT and O_EXCL were specified in oflag, but a queue with this name already exists.
  • EINVAL โ€” name doesn't follow the format described in mq_overview(7).
  • EINVAL โ€” O_CREAT was specified in oflag, and attr was not NULL, but attr->mq_maxmsg or attr->mq_msqsize was invalid. both of those fields must be greater than zero. also: in a process that is unprivileged (i.e. doesn't have the CAP_SYS_RESOURCE capability), attr->mq_maxmsg must be less than or equal to the msg_max limit, and attr->mq_msgsize must be less than or equal to the msgsize_max limit. and even in a privileged process, attr->mq_maxmsg cannot exceed the HARD_MAX limit. (mq_overview(7) has the details of all these limits โ€” go read it, i mean it.)
  • EMFILE โ€” the per-process limit on the number of open file and message queue descriptors has been reached (see the description of RLIMIT_NOFILE in getrlimit(2)). you opened too many, sorry bestie.
  • ENAMETOOLONG โ€” name was too long. ๐Ÿฅฒ
  • ENFILE โ€” the system-wide limit on the total number of open files and message queues has been reached. not just you, the whole system is booked.
  • ENOENT โ€” the O_CREAT flag was not specified in oflag, and no queue with this name exists.
  • ENOENT โ€” name was just "/" followed by no other characters. literally just a slash. nothing else. that's not a name, that's a mood. ๐Ÿ™ˆ
  • ENOMEM โ€” insufficient memory.
  • ENOSPC โ€” insufficient space for the creation of a new message queue. this probably happened because the queues_max limit was hit; see mq_overview(7).

๐Ÿ‘‘ ATTRIBUTES ๐Ÿ‘‘

for an explanation of the terms used in this section, see attributes(7).

  • Interface: mq_open() โ€” Attribute: Thread safety โ€” Value: MT-Safe

that's the whole table, and yes, MT-Safe is the flex. ๐Ÿ’…

๐ŸŒˆ VERSIONS ๐ŸŒˆ

C library/kernel differences (the tea โ˜•)

the mq_open() library function is implemented on top of a system call of the same name. and here's the twist: the library function does the check that name starts with a slash (/), and gives you the EINVAL error if it doesn't.

meanwhile the kernel system call expects name to contain no preceding slash. so the C library function passes name without the preceding slash โ€” that's name+1 โ€” to the system call. sneaky. iykyk. ๐Ÿงš

โญ STANDARDS โญ

POSIX.1-2008. certified.

๐ŸŽ€ HISTORY ๐ŸŽ€

POSIX.1-2001. yes she's been here a while, she's a legend. ๐Ÿ‘‘

๐Ÿ› BUGS ๐Ÿ›

before Linux 2.6.14, the process umask was not applied to the permissions specified in mode. so like... old kernel behaviour, be aware. ancient history but technically still a bug note. ๐Ÿ’€

๐ŸŒธ SEE ALSO ๐ŸŒธ

mq_close(3), mq_getattr(3), mq_notify(3), mq_receive(3), mq_send(3), mq_unlink(3), mq_overview(7)


and that's the whole page, bestie!! ๐Ÿซถ this was mq_open(3) from Linux man-pages 6.20, dated 2026-02-08. now go open a queue and make it iconic. ๐Ÿ’–โœจ๐ŸŽ€๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms