Question

I am sending message using message queue mechanism in C linux. But there is some problem with the msgrcv function. It's showing error as invalid argument. Please check this.

//msgrcv.c
#include"msgbuf.h"
int main()
{
      int msqid;
      key_t key;
      message_buf  *rbuf;
      rbuf=malloc(sizeof(*rbuf));
     // rbuf->m=malloc(sizeof(M1));

      key = ftok("/home/user",'a');
      if ((msqid = msgget(key, IPC_CREAT)) ==(key)-1)
      {
         perror("msgget");
         exit(1);
      }

      /* Receive an answer of message type 1.   */
      if (msgrcv(msqid, &rbuf, sizeof(rbuf->m), 1, 0) < 0)
      {
           perror("msgrcv");  //invalid argument to msgrcv
           exit(1);
       }
         /* Print the answer.  */
       printf("Received message text= %s\n", rbuf->m.cp);
      return 0;
   }

now msgbuf.h

 //msgbuf.h
typedef struct msgclient
{
   int msglen;
   int msgtype;
   char *cp;
}M1;

typedef struct msgbuf1
{
   long    mtype;
   M1      m;
} message_buf;

I also would like to know how two way comm happen using message queue. Do I need to make two message queues to get communication done between two processes? sample code for the same is also welcomed.

Thanks :)

Was it helpful?

Solution

I guess this

if ((msqid = msgget(key, 0666)) ==key-1)

should be

if ((msqid = msgget(key, 0666)) == -1)

From msgrcv

ERRORS
The msgrcv() function will fail if:
...
[EINVAL]
msqid is not a valid message queue identifier.

Furthermore, message_buf.m must not be a pointer but a member

typedef struct msgbuf1
{
   long    mtype;
   M1      m;
} message_buf;

You can then save this call to malloc

rbuf->m=malloc(sizeof(M1));

and the call to msgrcv should be

if (msgrcv(msqid, rbuf, sizeof(rbuf->m), 1, 0) < 0)

because otherwise, msgrcv will overwrite your stack.

Update:

From msgget

ERRORS
[ENOENT]
A message queue identifier does not exist for the argument key and (msgflg & IPC_CREAT) is 0.

This means, you must call

if ((msqid = msgget(key, IPC_CREAT | 0666)) == -1)

at least for the first time you call this function.

OTHER TIPS

I see one massive problem already:

message_buf  *rbuf;
rbuf=malloc(sizeof(rbuf));

Since rbuf is a pointer, you should be using

rbuf=malloc(sizeof(*rbuf));

Your original gives you the size of the pointer (usually four or eight bytes in current compilers) rather than the size of the message_buf structure that you need.

Another problem is your comparison with key-1 which I beleive should be (key)-1.

It's possible that your msgget is failing and, because of this faulty check, you're not detecting it. That means the msgrecv would be using -1 as the queue ID, explaining the failure there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top