Reputation: 1776
I have a test program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <mqueue.h>
#include <errno.h>
#include <fcntl.h>
int main() {
struct mq_attr attrs;
attrs.mq_maxmsg = 10;
attrs.mq_msgsize = sizeof(int);
const char name[] = "/test-queue";
mqd_t q = mq_open(name, O_CREAT | O_RDWR, 0600, &attrs);
if (q == (mqd_t)-1) {
perror("mq_open");
exit(EXIT_FAILURE);
}
mq_unlink(name); // it doesn't matter if I do this at the end or not
if (fork()) {
int msg = 666;
if (mq_send(q, (const char *)&msg, sizeof(msg), 1)) {
perror("mq_send");
exit(EXIT_FAILURE);
}
} else {
int msg;
unsigned priority;
if (mq_receive(q, (char *)&msg, sizeof(msg), &priority) == -1) {
perror("mq_receive");
exit(EXIT_FAILURE);
}
printf("%d\n", msg);
}
mq_close(q);
return 0;
}
I compile this program using gcc -std=c99 -Wall -o mqtest mqtest.c -lrt
on two platforms:
On Linux, everything works. On FreeBSD, I get mq_receive: Bad file descriptor
. Moving the mq_unlink
call to the end of main()
doesn't help. Is there a way to fix this, or do I have to postpone marking the queue for deletion and reopen it after the fork?
Upvotes: 2
Views: 719
Reputation: 43533
FreeBSD does preserve message queue descriptors. See mq_open(2):
FreeBSD implements message queue based on file descriptor. The descriptor is inherited by child after fork(2). The descriptor is closed in a new image after exec(3). The select(2) and kevent(2) system calls are supported for message queue descriptor.
Edit:
The structure that mqd_t
points to does contain a descriptor. But if you test that file descriptor just after the fork()
using fcntl()
, it also returns EBADF.
This is a bug in FreeBSD. But wether the bug is in the docs or in the implementation I cannot say.
Upvotes: 0