Skip to content

Instantly share code, notes, and snippets.

@aw
Last active September 15, 2020 03:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aw/50b1170c48062f397660468eed636f4e to your computer and use it in GitHub Desktop.
Save aw/50b1170c48062f397660468eed636f4e to your computer and use it in GitHub Desktop.
mq_attr struct size is 64 bytes, not 32

Problem

When parsing with PicoLisp (native) and the mq_getattr() call, I kept seeing errors such as:

corrupted size vs. prev_size

or

malloc(): invalid size (unsorted)

I noticed an issue with the kernel manpages documentation for POSIX message queues on Linux, which describes the mq_attr as having this structure:

struct mq_attr {
  long mq_flags;       /* Flags: 0 or O_NONBLOCK */
  long mq_maxmsg;      /* Max. # of messages on queue */
  long mq_msgsize;     /* Max. message size (bytes) */
  long mq_curmsgs;     /* # of messages currently in queue */
};

4 longs (8 bytes each = 32 bytes, right?)

However after viewing the mqueue.h header file, it is clear the struct is actually:

struct mq_attr {
  long mq_flags;       /* message queue flags                  */
  long mq_maxmsg;      /* maximum number of messages           */
  long mq_msgsize;     /* maximum message size                 */
  long mq_curmsgs;     /* number of messages currently queued  */
  long __reserved[4];  /* ignored for input, zeroed for output */
};

8 longs (64 bytes!)

Solution

Read 64-bytes instead of 32, because that's the actual size of the mq_attr struct.

Of course the __reserved field is useless, but if your program (FFI perhaps?) is reading the struct, you will possibly run into issues if you try to read 32B instead of 64B.

Just a small gotcha - always check the headers rather than relying on manpages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment