C Linux (Ubuntu) - msgsnd() и msgrcv() errno 22 (EINVAL)

Я пробую свои силы в IPC (передача сообщений) некоторое время, и я не могу решить эту проблему. errno 22 (EINVAL) для msgget () представляется неверным идентификатором очереди сообщений, неположительным типом сообщения или неверным размером сообщения. Теперь, errno 22 для msgrcv () является недействительным msgqid, или msgsz меньше 0, так что, похоже, это указывает на то, что мой идентификатор очереди неверен, поскольку недопустимый идентификатор msqueue перекрывается в двух объяснениях ошибок.

Я должен отметить, что мой вызов msgget () возвращает 0 в качестве идентификатора очереди. Это "должно" быть в порядке, так как в документах говорится, что любое неотрицательное возвращаемое значение допустимо. Есть идеи?

Выход из цикла после настройки счетчика на единицу (не нужно вставлять 100 сообщений об ошибках):

msqID = 0, sendMessage.msgText = Hola!: 0, sendMessage.msgType = 1, MSG_SIZE = 256 Ruh roh, в родительской отправке:: недопустимый аргумент child msgrcv(): msqID = 0, rcvMessage.msgText =, rcvMesage.msT 1, MSG_SIZE = 256 Ruh roh, в дочернем rcv:: неверный аргумент

Это терпит неудачу в строке 31 (первый msgsnd () в родительском процессе) и строке 60 (первый msgrcv () в дочернем процессе).

#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);
  }
}

1 ответ

Решение

Я долго смотрел на твой код, прежде чем смог обнаружить проблему.

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

Скобки не в том месте! Этот код эффективно назначает msgget(key, IPC_CREAT | 0666) == -1 в msqID, То есть, msqID является результатом условного и объясняет, почему msqID всегда 0,

Правильный код должен быть следующим. Обратите внимание на размещение скобок.

if((msqID = msgget(key, IPC_CREAT | 0666)) == -1)
Другие вопросы по тегам