Mihran Hovsepyan
Mihran Hovsepyan

Reputation: 11098

Simple IPC via linux messages

I'm trying to write some example of client-server application which uses linux messages. Here is my code:

#include <mqueue.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#define MSG_SIZE 4096
#define MSG_MAX_COUNT 1024
#define MSG_TYPE_TO_UPPER 0
#define MSG_TYPE_EXIT 1
#define MQ_NAME "msg_queue"

namespace {
    int str_toupper(char *str)
    {
        int len = 0;
        for(; str[len]; ++len) {
            str[len] = toupper(str[len]);
        }
        return len;
    }
}

int main(int argc, char** argv)
{
    if(argc != 2) {
        fprintf(stderr, "Usage: msg_queue (client|server)\n");
        exit(EXIT_FAILURE);
    }

    struct mq_attr attr;    // MQueue attributes
    mqd_t mqd;      // MQueue descriptor
    char buf[MSG_SIZE]; // Msg buffer
    unsigned int type;  // Msg type(priority)

    // Set up MQueue attributes
    attr.mq_maxmsg = MSG_MAX_COUNT;
    attr.mq_msgsize = MSG_SIZE;
    attr.mq_flags = 0;
    attr.mq_curmsgs = 0;

    mqd = mq_open(MQ_NAME, O_RDWR | O_CREAT, 0664, &attr);
    if(mqd == -1) {
        fprintf(stderr, "mq_open() failed for \""MQ_NAME"\": %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    if(strcmp(argv[1], "server") == 0) {
        while(mq_receive (mqd, buf, MSG_SIZE, &type) != -1) {
            if(type == MSG_TYPE_EXIT) {
                mq_unlink(MQ_NAME);
                mq_close(mqd);
                break;
            } else if(type == MSG_TYPE_TO_UPPER) {
                int len = str_toupper(buf);
                if(mq_send (mqd, buf, len, MSG_TYPE_TO_UPPER) == -1) {
                    fprintf(stderr, "Server: mq_send() failed: %s", strerror(errno));
                }
            }
        }
    } else if(strcmp(argv[1], "client") == 0) {
        while(1) {
            printf("Input a message: <type>(0 - TO_UPPER, 1 - EXIT) <message>\n");
            scanf("%u %s", &type, buf);

            if(mq_send (mqd, buf, strlen(buf), type) == -1) {
                fprintf(stderr, "Client: mq_send() failed: %s", strerror(errno));
            }

            if(type == MSG_TYPE_TO_UPPER) {
                if(mq_receive (mqd, buf, MSG_SIZE, &type) == -1) {
                    fprintf(stderr, "Client: mq_receive() failed: %s", strerror(errno));
                }
                printf("\"%s\" received\n", buf);
            } else if(type == MSG_TYPE_EXIT) {
                mq_unlink(MQ_NAME);
                mq_close(mqd);
                break;
            }
        }
    } else {
        fprintf(stderr, "Usage: msg_queue (client|server)\n");
        exit(EXIT_FAILURE);
    }
    return 0;
}

What is my mistake? It always prints error from the line 47 - fprintf(stderr, "mq_open() failed for \""MQ_NAME"\": %s\n", strerror(errno)); with errno = EINVAL.

Upvotes: 2

Views: 4965

Answers (1)

Mat
Mat

Reputation: 206699

I see two issues:

  • Your message queue name must begin with a / on Linux. See mq_overview(7):

Each message queue is identified by a name of the form /somename; that is, a null-terminated string of up to NAME_MAX (i.e., 255) characters consisting of an initial slash, followed by one or more characters, none of which are slashes.

  • MSG_MAX_COUNT is most likely above your system limits. It must be less than (or equal to) the /proc/sys/fs/mqueue/max_size. See mq_open(3):

EINVAL: 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.)

The other limit is probably ok, but you should verify it too.

Upvotes: 2

Related Questions