5

My Environment:

  • CentOS 6.5 (64bit kernel)
  • gcc 4.4.7 20120313

I am trying to set attribute for POSIX message queue, but the code does not change the attribute. I only get default attribute values.

Could you point out what the problem is with my code?

I execute the a.out as an user (not root).

#include <stdio.h>
#include <mqueue.h> // for message queue
#include <sys/stat.h>
#include <stdlib.h> // for EXIT_FAILURE
#include <string.h>

/*
gcc [file] -lrt
*/

static void showAttr(mqd_t mqd)
{
    struct mq_attr attr;

    mq_getattr(mqd, &attr);

    printf("maxmsg = %d\n", attr.mq_maxmsg);
    printf("msgsize = %d\n", attr.mq_msgsize);
    printf("curmsgs = %d\n", attr.mq_curmsgs);

}

int main()
{
    mqd_t mqd;
    int flags;
    int ret;
    struct mq_attr attr;

    flags = O_RDWR | O_CREAT;

    attr.mq_flags = 0; // or O_NONBLOCK
    attr.mq_maxmsg = 60;
    attr.mq_msgsize = 120;
    attr.mq_curmsgs = 0;

    // POSIX IPC name should start with "/"
    mqd = mq_open("/mq", flags,
//      (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
        0644,
        &attr );

    if (mqd < 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);
    }
    printf("open ok\n");

    sleep(1);

    showAttr(mqd);

    ret = mq_close(mqd);
    if (ret != 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);     
    }
    printf("close ok\n");

    return 0;
}

I found that following code works. However, when I try to set attr.mq_maxmsg (=60), the mq_open fails.

#include <stdio.h>
#include <mqueue.h> // for message queue
#include <sys/stat.h>
#include <stdlib.h> // for EXIT_FAILURE
#include <string.h>
#include <errno.h>

/*
gcc [file] -lrt
*/

static void showAttr(mqd_t mqd)
{
    struct mq_attr attr;

    mq_getattr(mqd, &attr);

    printf("maxmsg = %d\n", attr.mq_maxmsg);
    printf("msgsize = %d\n", attr.mq_msgsize);
    printf("curmsgs = %d\n", attr.mq_curmsgs);

}

int main()
{
    mqd_t mqd;
    int flags;
    int ret;
    struct mq_attr attr;

    flags = O_RDWR | O_CREAT;

    // POSIX IPC name should start with "/"

    // 1. once open without attribute setting
    mqd = mq_open("/mq", flags,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
    mq_getattr(mqd, &attr);
    mq_unlink("/mq");
    mq_close(mqd);

    // 2. set values of attribute
    // attr.mq_maxmsg = 10;
    attr.mq_msgsize = 120;

    // 3. allocate attribute
    mqd = mq_open("/mq", flags,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
    //   0644,
        &attr );

    if (mqd < 0) {
        printf("open failed %d\n", mqd);
        exit(EXIT_FAILURE);
    }
    printf("open ok\n");

    sleep(1);

    showAttr(mqd);


    ret = mq_close(mqd);
    if (ret != 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);     
    }
    printf("close ok\n");

    return 0;
}
1
  • Mentioning that setting values higher than max allowed caused the failure and pointing to where max values are defined was a huge help. Many thanks. Commented Oct 18, 2015 at 17:32

2 Answers 2

4

The following code works.

I used mq_unlink() before mq_open() as pilcrow suggested.

And, the other source of the problem was I set attr.mq_maxmsg greather than 10 (which is defined in /proc/sys/fs/mqueue/msg_max ). If I set attr.mq_maxmsg less than and equal to 10, these is no problem for setting attribute.

#include <stdio.h>
#include <mqueue.h> // for message queue
#include <sys/stat.h>
#include <stdlib.h> // for EXIT_FAILURE
#include <string.h>
#include <errno.h>

/*
gcc [file] -lrt
*/

static void showAttr(mqd_t mqd)
{
    struct mq_attr attr;

    mq_getattr(mqd, &attr);

    printf("maxmsg = %d\n", attr.mq_maxmsg);
    printf("msgsize = %d\n", attr.mq_msgsize);
    printf("curmsgs = %d\n", attr.mq_curmsgs);

}

int main()
{
    mqd_t mqd;
    int flags;
    int ret;
    struct mq_attr attr;

    flags = O_RDWR | O_CREAT;

    mq_unlink("/mq");

    attr.mq_flags = 0;
    attr.mq_maxmsg = 3; // ***
    attr.mq_msgsize = 141;
    attr.mq_curmsgs = 0;

    mqd = mq_open("/mq", flags,
        (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),
        &attr );

    if (mqd < 0) {
        printf("open failed %d\n", mqd);
        exit(EXIT_FAILURE);
    }
    printf("open ok\n");

    sleep(1);

    showAttr(mqd);


    ret = mq_close(mqd);
    if (ret != 0) {
        printf("open failed\n");
        exit(EXIT_FAILURE);     
    }
    printf("close ok\n");

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

2

mq_open() is returning an already existing queue whose attributes were set at the time it was created. The O_CREAT flag thus has no effect, and the attributes you specify are ignored as well.

Call mq_unlink() before your open, and perhaps set O_EXCL as well, and see the difference.

3 Comments

@ pilcrow: Thank you for your reply. I added "mq_unlink("/mq"); before mq_open(), but I get "open failed". I also tried O_EXCL, but it was not successful.
@sevenOfNine, what errno? Sounds like a different and new problem.
@ pilcrow: mq_open return -1. It seems I have the problem similar to stackoverflow.com/questions/21465734/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.