Messages
========
A message resource is described by a struct `msqid_ds' which is
allocated and initialized when the resource is created. Some fields in
`msqid_ds' can then be altered (if desired) by invoking `msgctl'. The
memory used by the resource is released when it is destroyed by a
`msgctl' call.
struct msqid_ds
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue (internal) */
struct msg *msg_last; /* last message in queue (internal) */
time_t msg_stime; /* last msgsnd time */
time_t msg_rtime; /* last msgrcv time */
time_t msg_ctime; /* last change time */
struct wait_queue *wwait; /* writers waiting (internal) */
struct wait_queue *rwait; /* readers waiting (internal) */
ushort msg_cbytes; /* number of bytes used on queue */
ushort msg_qnum; /* number of messages in queue */
ushort msg_qbytes; /* max number of bytes on queue */
ushort msg_lspid; /* pid of last msgsnd */
ushort msg_lrpid; /* pid of last msgrcv */
To send or receive a message the user allocates a structure that
looks like a `msgbuf' but with an array `mtext' of the required size.
Messages have a type (positive integer) associated with them so that
(for example) a listener can choose to receive only messages of a given
type.
struct msgbuf
long mtype; type of message (Note:msgrcv).
char mtext[1]; message text .. why is this not a ptr?
The user must have write permissions to send and read permissions to
receive messages on a queue.
When `msgsnd' is invoked, the user's message is copied into an
internal struct `msg' and added to the queue. A `msgrcv' will then read
this message and free the associated struct `msg'.