0

親プロセスとそのフォークされた子の間のメッセージ キューを介して 1KB の文字列を送信しようとしています。残念ながら、 、 などへの呼び出しmsgsndmsgrcv突然すべて -1 を返し、EINVALエラーが発生します。

このエラー (msgsndたとえば の場合) がmsqid無効な場合、メッセージ タイプ引数が <1 に設定されている場合、またはmsgszが範囲外の場合に発生することがわかりました。しかし、テストすると、私が知る限りmsgget、完全に有効な ID 番号が返され、タイプは適切に設定されています。バッファー範囲に問題があるに違いありませんが、正しく設定したと思います。コードには、説明するコメントを追加しました (必死に追加された #includes のすべてについて申し訳ありません)。

#include <errno.h>  
#include <stdio.h>
#include <iostream> 
#include <stdlib.h>
#include <string.h>
#include <string> 
#include <cstring> 
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <sstream> 

#define PERMS (S_IRUSR | S_IWUSR) 
#define NUMBYTES 1024 //number of chars (bytes) to be sent 

using namespace std; 

//Special structure for messages
typedef struct {
  long mtype; 
  char mtext[NUMBYTES];  
} mymsg_t; 

int main(){

  //Construct a generic test message of the specified size
  char message[NUMBYTES];
  for(int i = 0; i < NUMBYTES; i++)
    message[i] = 'a';  

  //Create the message queue (accessed by both parent
  //and child processes)
  int msqid;
  int len;  
  if(msqid = msgget(IPC_PRIVATE, PERMS) == -1)
    perror("Failed to create new message queue!\n");   

  if(fork() == 0){  //Child process...does the sending

    mymsg_t* mbuf;
    len = sizeof(mymsg_t) + strlen(message); //doesn't work with " + sizeof(message)" either 

    void* space; 
    if((space = malloc(len)) == NULL) //this works fine; no error output 
      perror("Failed to allocate buffer for message queue.\n"); 
    mbuf = (mymsg_t*)space;  

    strcpy(mbuf->mtext, message); 
    mbuf->mtype = 1; //a default   

//Some error checks I tried... 
//cout<<"msqid is " << msqid << endl;
//cout << "mbuf ptr size is " << sizeof(mbuf) << ". And this non-ptr: "<<sizeof(*mbuf)<<". And 
//len: "<<len<<endl; 

    if(msgsnd(msqid, mbuf, len+1, 0) == -1)
      perror("Failed to send message.\n");  //this error occurs every time! 

    free(mbuf);  
  }    

  else{ //Parent process...does the receiving 

    usleep(10000); //Let the message come     

    mymsg_t mymsg; //buffer to hold message
    int size; 
    if((size = msgrcv(msqid, &mymsg, len+1, 0, 0)) == -1) //error every time
      perror("Failed to read message queue.\n");  

    //checking that it made it 
    //cout << "Hopefully printing it now? : " << endl; 
    //if(write(STDOUT_FILENO, mymsg.mtext, size) == -1)
    //  perror("Failed to write to standard output!\n"); 


  }

  ostringstream oss;
  oss << "ipcrm -q " << msqid; 
  string command = oss.str(); 

  if(system(command.c_str()) != 0)  //also errors every time, but not main focus here 
    perror("Failed to clean up message queue!"); 
}

ここで何が起こっているのですか?バッファー手順が正常に機能し、十分なスペースがあると思いました..

4

0 に答える 0