Why is errno set to 22: mq_open() POSIX

cmessage-queueposix


Im receiving errno 22 when trying to create a message_queue in POSIX with C.
As far as I can tell, by comparing to example code available on the web, I've set the parameters correctly.

Here is a snippet:

    int open_flags;
    mqd_t mqfd;
    int bytes_per_msg;
    struct mq_attr attr;
    unsigned int* msgbuff;

    printf("from 1 to 400, what is N? : ");
    scanf("%d", &n);
    bytes_per_msg = (n + 1) * (sizeof(unsigned int));
    msgbuff = (unsigned int*)malloc(bytes_per_msg);

    open_flags = O_CREAT|O_RDWR;
    attr.mq_maxmsg = n;
    attr.mq_msgsize = bytes_per_msg;
    attr.mq_flags   = 0;


    mqfd = mq_open("/myqueue", open_flags, 0666, &attr);

    if(mqfd == -1){
        printf("queue creation failed, ERRNO: %d\n",errno);
    }

EDIT: My apologies for not being more clear. Errno 22 is INVALID ARGUMENT.
–The meanings of the error numbers can be found on errno.h

Best Answer

I assume you are using mq_open(3) on Linux, and errno getting EINVAL. According to the documentation it may happen when:

name doesn't follow the format in mq_overview(7).

or

O_CREAT was specified in oflag, and attr was not NULL, but attr->mq_maxmsg or attr->mq_msqsize was invalid. Both of these fields must be greater than zero. In a process that is unprivileged (does not 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. In addition, even in a privileged process, attr->mq_maxmsg cannot exceed the HARD_MAX limit. (See mq_overview(7) for details of these limits.)

So you should also read mq_overview(7)

BTW, reading the manual is always faster than asking on some forum like here.

Next time, use perror(3) on error cases. Notice that POSIX errno.h specification does not assign numerical values to error numbers like EINVAL (and that is on purpose, several POSIX compliant systems could have different numbers).

BTW, you should always check the return value of scanf(3), in your case:

printf("from 1 to 400, what is N? : \n");
n= 0;
if (scanf("%d", &n)<1 || n<=0 || n>400) { 
  fprintf(stderr, "bad number (n=%d)\n", n);
  exit(EXIT_FAILURE);
}