msgrcv: Invalid argument Error
I am getting an error that says:
msgrcv: Invalid argument
what could be causing this error? Here is my code
Bassically I'm passing a message from a parent to a child then I want to pass a message from the child to the parent and even though I'm using basically the same code for both, it isn't working for the second receive.
struct msg {
long int mtype; /* message type */
char mtext[1024]; /* message text */
} msg;
int len, msgflg = 0, msqid, *pint;
pid_t pid;
size_t msgsz = 40;
long int msgtyp;
msqid = msgget(IPC_PRIVATE,S_IRWXU);
char* charpid[250];
msg.mtype = 1;
if (msqid < 0) {
perror("msgget");
exit(1);
}
switch(pid=fork()) //fork child process
{
case 0: //Child process
//receive message from parent
if(msgrcv(msqid,&msg,sizeof msg.mtext, 1,IPC_NOWAIT)>=0){
printf("Serving for client pid #%s",msg.mtext);
asprintf(&charpid[0], "%ld\n", pid);
strncpy(msg.mtext,charpid[0], 1024);
if(msgsnd(msqid,&msg,strlen(msg.mtext),msgflg)<0){
pe开发者_运维百科rror("msgsnd");
}
}
else
perror("msgrcv");
msgctl(msqid, IPC_RMID, NULL);
exit(0);
case -1:
printf("fork failed");
exit(2);
break;
default:
//convert pid to string.
asprintf(&charpid[0], "%ld\n", pid);
//set mtext
strncpy(msg.mtext,charpid[0], 1024);
//send message
if(msgsnd(msqid,&msg,strlen(msg.mtext),msgflg)<0){
//report error
perror("msgsnd");
}
//wait for child process to die
wait(NULL);
//receive message from child
if(msgrcv(msqid,&msg,sizeof msg.mtext, msg.mtype,IPC_NOWAIT)>=0){
//print pid
printf("Received reply from pid #%s",msg.mtext);
}
else
//report error
perror("msgrcv");
exit(0);
}
The "Invalid argument" error is from your original process (not the forked child), and occurs when it tries to receive the reply from the child. The error occurs because the child has already removed the queue by then. Since your original process created the queue and waits for the child to exit anyway, it would make more sense to remove the queue there (after receiving the reply).
Even if you fix that, you may still find that when the child does its msgrcv
it might not get anything, since your original process may not have sent it yet (and you specify IPC_NOWAIT
). To get your code to work, with both receives, I had to move the msgctl
call as noted above, and also add a sleep
call before the msgrcv
in the child.
精彩评论