tags:

views:

73

answers:

1

I am writing a code in C on a unix system. I have created a message queue server. Each time I receive a new message I fork and the child process handles the new client. The server waits for new client. Here's the code.

for (;;)

{

  struct my_msgbuf buf;

  if (msgrcv (msqid, &(buf.mtype), sizeof (buf), 1, 0) == -1)
  perror ("msgrcv");


if((pid = fork())<0)
perror("fork");


if(pid==0)
{
 //child code
}

}

Now the code works for the first iteration but on the second iteration msgrcv gives the following error - msgrcv: Invalid Arguments instead of waiting for new messages.

How do I fix this?

A: 

msgrcv does take a msgsz parameter, but it's not the size of a struct my_msgbuf, rather, it's the number of bytes in the mtext[] field of the structure.

You aren't really supposed to use struct msgbuf directly, I think. It would be normal to define your own with appropriate space. The way you have it, your buf declaration allocates only 1 byte, and then the code tells the kernel that you have sizeof buf bytes, which you don't. As a result, the code is said to invoke Undefined Behavior or UB.

This may or may not explain the EINVAL but one should always fix the known bugs and retest because UB taints further analysis...

DigitalRoss
no didnt work...
Peter
The code doesn't show an assignment to `mtype`. Is it getting set reasonably?
DigitalRoss
yes its datatype is long in the structure
Peter
Sure, but are you setting to a positive number identifying a message type in a queue? Not sure what Unix you are on but on my linux man page is says the following about sources of EINVAL: Invalid msqid value, or non-positive mtype value, or invalid msgsz value (less than 0 or greater than the system value MSG‐ MAX).
DigitalRoss
yes I am doing that
Peter