Search code examples
clinuxipcftokmsgsend

error: Invalid argument; while sending msgsnd() message; not matching queue ID


I was just learning IPC on linux and come up with three simple programs. One is made to create (and administrate in the feature) the message queue. The second should just send the message to the queue created by the first one. The third program is receiving data from the queue.

All programs are inheriting from the same root directory and spiting in to separate directories per source and binaries.

So lets just focus on creating and sending part, and that shall help me fix the third program as well.

add queue main.c:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define FAILED -1


int main(int argc, char *argv[]) {
  // message data
  key_t key;
  int msgqid;

  if ((key = ftok("../src/main.c", 'Z')) == FAILED) {
    perror("ftok");
    exit(1);
  }

  if ((msgqid = msgget(key, 0666 | IPC_CREAT)) == FAILED) { /* create an message queue with owner & group & others permission set to rw- */
    perror("msgget");
    exit(1);
  }

  printf("Message Queue %i with key %i, been created [press return to delete]", msgqid, key);
  getchar();

  if (msgctl(msgqid, IPC_RMID, NULL) == FAILED) {
    perror("msgctl");
    exit(1);
  }
  printf("I'm outta here! \n");

  return 0;
}

send main.c:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/msg.h>
#include <stddef.h>
#include <string.h>

#include "../../lib/shared_msgbuf.h" /* mbuf, MSGSZ */

#define FAILED -1


int main(void) {
  char s[MSGSZ];

  printf("Enter a message: ");

  if (fgets(s, sizeof s, stdin) == NULL)
    perror("fgets");
  else 
    strcpy(mbuf.mtext, s);

  printf("Connecting to the queue... \n", s);

  // Setup
  key_t key;
  int msgqid;

  if ((key = ftok("../../adqueue/src/main.c", 'Z')) == FAILED) {
    perror("ftok");
    exit(1);
  }

  if (msgqid = msgget(key, 0666) == FAILED) {
    perror("msget");
    exit(1);
  }

  printf("\n*CONNECTION ESTABLISHED* \n");
  printf("queue id: %i \n", msgqid);
  printf("queue key: %d \n", key);
  printf("message: %s \n", s);

  printf("Sending the message... \n");
  if (msgsnd(msgqid, &mbuf, MSGSZ, 0) == FAILED) {
    perror("msgsnd");
    exit(0);
  }

  return 0;
}

So the problem is that I'm getting Invalid argument error number when trying to send the message. Looking at the data, I can't get why the id is not matching since connection to the queue seems to work...

Exemplar data:

./cadqueue 
Message Queue 327680 with key 1510081535, been created [press return to delete]

./send 
Enter a message: test
Connecting to the queue... 

*CONNECTION ESTABLISHED* 
queue id: 0 
queue key: 1510081535 
message: test

Sending the message... 
msgsnd: Invalid argument

Solution

  • Your error comes from this line:

    if (msgqid = msgget(key, 0666) == FAILED) {
    

    It should be

    if ((msgqid = msgget(key, 0666)) == FAILED) {
    

    In first case, because of operator priority, comparison (==) is done before assignation (=).

    In second case, paranthesis tells compiler what must be done first.