Reputation: 111
I am new to message queues. Basically what I am trying to do here is, I fork and make a user processes. After the fork() I send a message to the user process and wait for a message back from user message. In the actual program I am using while(1) to loop like this with 100 user processes. To make sure I send message and receive message only from one particular user process at a time I used user process PID as the 4th argument in message receive and I make the message type =getpid() when I send the message. I am getting an invalid argument error. I tried to change the permission bits to 0666 but when I do this the program goes in an infinite loop. When the permission is 0777 I get the following result. Here is the minimal working code of what I did. Please excuse the long list of headers.
oss.c
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# include <sys/wait.h>
//global variables
int shmid;
int msgid;
key_t shmkey;
int currentprocessPID;
int key= 11223344;
void startprocess();
struct mesg_buffer {
long mesg_type;
int mesg_text[4];
} message;
/*mesg.text[0]-Stores PID
mesg.text[1]-stores CPU time used by process seconds
mesg.text[2]= stores CPU time used by process nanoseconds
*/
int main(int argc, char **argv)
{
if((msgid = msgget(key, 0777 | IPC_CREAT))==-1)
perror("error in msg get");
printf("going to fork");
pid_t pID = fork();
if (pID < 0)
{
perror("Failed to fork:");
exit(EXIT_FAILURE);
}
else if (pID == 0)
{
static char *args[]={"./user",NULL};
int status;
if(( status= (execv(args[0], args)))==-1)
{
perror("oss:failed to execv");
exit(EXIT_FAILURE);
}
else
printf("\n message sent to user sucessfully");
}
currentprocessPID=pID;
message.mesg_type = currentprocessPID;
if( msgsnd(msgid, &message, sizeof(message), 0)==-1)
perror("error in sending message to user process");
else
{
printf("\nmessage sent to process %d",currentprocessPID);
}
if(msgrcv(msgid, &message, sizeof(message), currentprocessPID, 0)==-1)
perror("error in recieving message from user process");
else
{
int corpse,status;
while ((corpse = waitpid(message.mesg_text[0], &status, 0)) != message.mesg_text[0] && corpse != -1)
{
char pmsg[64];
snprintf(pmsg, sizeof(pmsg), "logParse: PID %d exited with status 0x%.4X", corpse, status);
perror(pmsg);
}
printf("\n%d process is done with its work",message.mesg_text[0]);
}
return 0;
exit(0);
}
user.c
//copy same headers as above
int shmid;
int key= 11223344;
struct mesg_buffer {
long mesg_type;
int mesg_text[4];
} message;
void main()
{
int pid=getpid();
printf("\n\nhello from %d",getpid());
int times=0,timen=0,zero=0,randomnum,timelimit,n=0,sum,i,locals=0,localn=0;
int msgid = msgget(key, 0666 | IPC_CREAT);
if(msgid==-1)
{
perror("User:error in message get");
exit(0);
}
if(msgrcv(msgid, &message, sizeof(message), pid, 0)==-1)
{
perror("User: Error in receieving message from OSS");
exit(0);
}
else
{
printf("\nIn User: Data received ");
message.mesg_type = pid;
message.mesg_text[0]=pid;
message.mesg_text[1] = locals;
message.mesg_text[2]=localn;
message.mesg_text[3]=1;
if( msgsnd(msgid, &message, sizeof(message), 0)==-1)
perror("error in sending message back to OSS");
exit(0);
}
exit(0);
}
This is the output that I get:
error in msg get: Permission denied
error in sending message to user process: Invalid argument
error in recieving message from user process: Invalid argument
going to fork
In the actual program which is like 500 lines, I used permission bits 0666. In that program I get a identifier removed error when the user process tries to receive message from oss.
Upvotes: 1
Views: 459
Reputation: 111
So after suffering for more than a day (researching for answers) My professor pointed out that I was sending the message to user process before it even had the message queues setup. All I had to do was add sleep(1); after message was sent from oss.
Upvotes: 0
Reputation: 27632
You probably ran an earlier version of the program where you gave the wrong permissions with IPC_CREAT, or where you forgot to add any permissions at all (making them all zero), and that message queue is still there, with those permissions. I have done this myself a few times. This will give a "Permission denied" error in msgget, and later "Invalid argument" in msgsnd and msgrcv. Try another key.
Remember that a message queue is a permanent thing, similar to a file. Once you have created it, it stays there on your computer until you remove it (or reboot the computer), even after your program has exited.
And another thing: Remember that standard output is line buffered, meaning it doesn't actually print anything until it gets a newline to print, and my advice is to replace all your printf("\nWhatever")
with printf("Whatever\n")
, otherwise you might not see the output when you expect to see it.
Upvotes: 1