Search code examples
clinuxipcmessage-queuemsgrcv

error in msgrcv() :receiving data through message queue in C


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


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.