1

I'm trying my hand at IPC (message passing) for a while now, and I'm unable to resolve this problem. errno 22 (EINVAL) for msgget() seems to be Invalid message queue identifier, nonpositive message type, or invalid message size. Now, errno 22 for msgrcv() is msgqid invalid, or msgsz less than 0, so this seems to point to my Queue ID being wrong since invalid msqueue id overlaps in the two error explanations.

I should note that my msgget() call returns 0 as the queue ID. This 'should' be fine, as the docs say that any non-negative return value is valid. Any ideas?

Output from a run after adjusting the counter to one (don't want to paste 100 error messages):

msqID = 0, sendMessage.msgText = Hola!: 0, sendMessage.msgType = 1, MSG_SIZE = 256 Ruh roh, in parent send: : Invalid argument child msgrcv(): msqID = 0, rcvMessage.msgText = , rcvMesage.msgType = 1, MSG_SIZE = 256 Ruh roh, in child rcv: : Invalid argument

This fails on line line 31 (first msgsnd() in the parent process) and line 60 (first msgrcv() in the child process).

#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
const int MAX_TEXT_SIZE = 255;
const int COUNTER = 99;
int main(){
  srand(time(NULL));
  int childPID, key = rand(), msgSendRslt, msgRecvRslt, msqID;
  long int type  = 1;
  struct msg {long msgType; char msgText[MAX_TEXT_SIZE];};
  const int MSG_SIZE = sizeof(struct msg)-sizeof(long int);
    if(msqID = msgget(key, IPC_CREAT | 0666) == -1){
      perror("\nRuh roh: ");
      exit(1);
    }
    if((childPID = fork()) > 0){
      struct msg sendMessage, rcvMessage;
      sendMessage.msgType = type;
      char *sendMsg = malloc(MAX_TEXT_SIZE);
      for(int i = 0; i < 100; i++){
        sprintf(sendMsg, "Hola!: %d", i);
        strcpy(sendMessage.msgText, sendMsg);
        printf("\nmsqID = %d, sendMessage.msgText = %s, sendMessage.msgType = %ld, MSG_SIZE = %d", msqID, sendMessage.msgText, sendMessage.msgType, MSG_SIZE);
        printf("\n");
        if(msgsnd(msqID, &sendMsg, MSG_SIZE, IPC_NOWAIT) != -1){
          printf("\nFrom parent, sent msg %d", i);
          if(msgrcv(msqID, &rcvMessage, MSG_SIZE, rcvMessage.msgType, IPC_NOWAIT) != -1){;
            printf("\nIn the parent, received from child: %s", rcvMessage.msgText);
          }
          else
            perror("\nRuh roh, in parent rcv: ");
        }
        else
          perror("\nRuh roh, in parent send: ");
          printf("\nerrno: %d", errno);
      }
      strcpy(sendMessage.msgText, "Over and out!");
      if(msgsnd(msqID, &sendMsg, MSG_SIZE, 0) == -1)
        perror("\nRuh roh, in parent send at end: ");
    }
  else if (childPID == 0){ //child
    int count = 0;
    int test = ceil(3.8);
    char *countS = malloc(ceil(log(COUNTER)/log(10)));
    struct msg rcvMessage, sendMessage;
    strcpy(rcvMessage.msgText, "");
    sendMessage.msgType = type;
    rcvMessage.msgType = type;
    while(strcmp(rcvMessage.msgText, "Over and out!") != 0){
      sprintf(countS, "%d", count);
      strcat(strcpy(sendMessage.msgText, "10-4 good buddy!: "), countS);
      printf("\nchild msgrcv(): msqID = %d, rcvMessage.msgText = %s, rcvMesage.msgType = %ld, MSG_SIZE = %d", msqID, rcvMessage.msgText, rcvMessage.msgType, MSG_SIZE);
      printf("\n");
      if(msgrcv(msqID, &rcvMessage, MSG_SIZE, rcvMessage.msgType, IPC_NOWAIT) != -1){
        printf("\nIn the child, received from the parent: %s", rcvMessage.msgText);
        if(msgsnd(msqID, &sendMessage, MSG_SIZE, IPC_NOWAIT) == -1)
          perror("\nRuh roh, in child send: ");
          exit(1);
      }
      else
        perror("Ruh roh, in child rcv: ");
        printf("\nChild error: %d", errno);
        exit(1);
    }
  }
  else{
    perror("\nRuh roh, fork() problem: ");
    printf("\n");
    exit(1);
  }
}
patricio2626
  • 147
  • 1
  • 3
  • 17
  • Please clarify your question. Which functions exactly are failing? Your title refers to `sendmsg` and `recvmsg` but the code shown does not have any calls to these functions. Do you mean `msgsnd` and `msgrcv`? In any case, you have multiple calls of all those functions. Which of those exactly are failing and what is the diagnostic output of your program? You need to help us by giving all the relevant info. – kaylum Nov 25 '15 at 22:18
  • I just included sys/types.h but it didn't change anything in the behavior. – patricio2626 Nov 26 '15 at 01:30

1 Answers1

2

I stared at your code for such a long time before I could spot the problem.

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

The parentheses are in the wrong place! That code effectively assigns msgget(key, IPC_CREAT | 0666) == -1 to msqID. That is, msqID is a result of a conditional and explains why msqID is always 0.

The correct code should be as follows. Take note of the placement of the parentheses.

if((msqID = msgget(key, IPC_CREAT | 0666)) == -1)
kaylum
  • 13,833
  • 2
  • 22
  • 31