On 27 May 2008 at 10:59, bernd wrote:
Quote:
I create a message queue with msgget(), sent a 5-byte message to it
with msgsnd() and try to receive the queue's content with msgrcv().
Everything seems to work fine, apart from the fact that I get back
only the last byte back from the original message (after sending the
message ipcs -qA shows clearly that there are 5 Bytes waiting in the
queue).
First up, there are several minor problems with your code (a missing
header, wrong format specifier for printf, an assignment needing
parentheses to do what you want it to do...), all of which you can find
by turning up the warning level on gcc. Another fairly serious problem
is that you declare an array of length msgsz, where msgsz is a variable.
You can't do that, even with C99's VLAs, since your array is a member of
a structure.
For now, let's replace
Quote:
size_t msgsz = 5 ;
with
#define msgsz 6
which will also give us space for the null-terminator at the end of the
"hello" string.
As to your actual problem, it's in the sending stage.
Quote:
struct message {
long mtype ;
const char *mpointer ;
} ;
struct message msg ;
>
msg.mtype = 0 ;
msg.mpointer = "hello" ;
>
if ( msgsnd( msqid, msg.mpointer, msgsz, msgflg ) == 0 ) {
[snip]
The first thing to note is that msg.mtype must be 0.
The second thing is that the second argument to msgsnd needs to be a
pointer to a struct message: use &msg instead of msg.mpointer.
But the really slippery point is that this is one of those occasions
when arrays and pointers aren't interchangeable. Let's suppose for the
sake of argument that msg.mpointer is at address 0xDEADBEEF, and think
about what msgsnd is going to do when you pass it &msg. It will try to
read msgsz (i.e. 6) characters from memory locations 0xDEADBEEF,
0xDEADBEF0, ..., 0xDEADBEF4. That's unfortunate, because 0xDEADBEEF
through 0xDEADBEF2 (on a 32-bit system) contain a pointer to the string
literal "hello" in the data segment of your program, while the last two
bytes are garbage.
So you should change the sending code to look like this:
struct message {
long mtype ;
char mtext[msgsz];
} ;
struct message msg;
msg.mtype = 1;
strcpy(msg.mtext, "hello");
if ( msgsnd( msqid, &msg, msgsz, msgflg ) == 0 ) {
...