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 ifO_CREATwas also inoflag, and a queue with that name already exists, it fails with the errorEEXIST. no duplicates, periodt.O_NONBLOCKโ open the queue in nonblocking mode. in the situations wheremq_receive(3)andmq_send(3)would normally just sit there and block, they instead fail with the errorEAGAIN. 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โ bothO_CREATandO_EXCLwere specified inoflag, but a queue with this name already exists.EINVALโ name doesn't follow the format described inmq_overview(7).EINVALโO_CREATwas specified inoflag, andattrwas notNULL, butattr->mq_maxmsgorattr->mq_msqsizewas invalid. both of those fields must be greater than zero. also: in a process that is unprivileged (i.e. doesn't have theCAP_SYS_RESOURCEcapability),attr->mq_maxmsgmust be less than or equal to themsg_maxlimit, andattr->mq_msgsizemust be less than or equal to themsgsize_maxlimit. and even in a privileged process,attr->mq_maxmsgcannot exceed theHARD_MAXlimit. (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 ofRLIMIT_NOFILEingetrlimit(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โ theO_CREATflag was not specified inoflag, 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 thequeues_maxlimit was hit; seemq_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
- Copyright 2006, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms