Message Queue Operations
Message queues are used to send and receive messages. An actual message, from the system's standpoint, is defined by the msgbuf structure found in the header file as
struct msgbuf { long int mtype; /* type of received/sent message */ char mtext[1]; /* text of the message */ };
This structure is used as a template for the messages to be sent to and received from the message queue.
The first member of the msgbuf structure is the message type. The message type, mtype , is a long integer value and is normally greater than 0. The message type, generated by the process that originates the message, is used to indicate the kind (category) of the message. The type value is used by the msgrcv system call to selectively retrieve messages falling within certain boundary conditions. Messages are placed in the message queue in the order they are sent and not grouped by their message type.
Following mtype is the reference to the body of the message. As shown, this is defined as a character array with one element: mtext[1] . In actuality, any valid structure member(s), character arrays or otherwise , that make up a message can be placed after the requisite mtype entry. The system assumes a valid message always consists of a long integer followed by a series of 0 or more bytes (the organization of the data bytes is the programmer's prerogative). It is the address of the first structure member after mtype that the system uses as its reference when manipulating the msg structure (discussed in Section 6.3). Therefore, users can generate their own message structures to be placed in the message queue so long as the first member (on most systems this is the first four bytes) is occupied by a long integer.
Messages are placed in the message queue (sent) using the system call msgsnd (Table 6.9).
Table 6.9. Summary of the msggnd System Call.
Include File(s) |
|
Manual Section |
2 |
|
Summary |
int msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); |
|||
Return |
Success |
Failure |
Sets errno |
|
-1 |
Yes |
The msgsnd system call requires four arguments. The first argument, msqid , is a valid message queue identifier returned from a prior msgget system call. The second argument, msgp , is a pointer to the message to be sent. As noted, the message is a structure with the first member being of the type long integer. The message structure must be allocated (and hopefully initialized ) prior to its being sent. The third argument, msgsz , is the size (number of bytes) of the message to be sent. The size of the message is the amount of storage allocated for the message structure minus the storage used for the message type (stored as a long integer). The message size can be from 0 to the system-imposed limit. The fourth argument to msgsnd , msgflg , is used to indicate what action should be taken if system limits for the message queue (e.g., the limit for the number of bytes in a message queue) have been reached. The msgflg can be set to IPC_NOWAIT or to 0. If set to IPC_NOWAIT and a system limit has been reached, msgsnd will not send the message and will return to the calling process immediately with errno set to EAGAIN. If msgflg is set to 0, msgsnd will block until the limit is no longer at system maximum (at which time the message is sent), the message queue is removed, or the calling process catches a signal. The system uses the msgsz argument to msgsnd as its msg.msg_ts value, the msgbuf.mtype value as its msg.msg_type , and the msgbuf.mtext reference as msg.msg_spot .
If msgsnd is successful, it returns a value of 0; otherwise, it returns a value of -1 and sets errno to indicate the nature of the error. See Table 6.10.
Table 6.10. msgsnd Error Messages.
# |
Constant |
perror Message |
Explanation |
---|---|---|---|
4 |
EINTR |
Interrupted system call |
When sleeping on a full message queue, the process received an interrupt. |
11 |
EAGAIN |
Resource temporarily unavailable |
Message cannot be sent ( msg_qbyte limit exceeded) and IPC_NOWAIT was specified. |
12 |
ENOMEM |
Cannot allocate memory |
Insufficient system memory to copy message. |
13 |
EACCES |
Permission denied |
Calling process lacks write access for the message queue. |
14 |
EFAULT |
Bad address |
msgp references a bad address. |
22 |
EINVAL |
Invalid argument |
|
43 |
EIDRM |
Identifier removed |
Message queue has been removed. |
Messages are retrieved from the message queue using the system call msgrcv , summarized in Table 6.11.
Table 6.11. Summary of the msgrcv System Call.
Include File(s) |
|
Manual Section |
2 |
|
Summary |
ssize_t msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg); |
|||
Return |
Success |
Failure |
Sets errno |
|
Number of bytes actually received |
-1 |
Yes |
The msgrcv system call takes five arguments. The first, as for the msgsnd system call, is the message queue identifier. The second, msgp , is a pointer to the location (structure) where the received message will be placed. The receiving location should have as its first field a long integer to accommodate the message type information. The third argument, msgsz , is the maximum size of the message in bytes. This value should be equal to the longest message to be received. Truncation of the message will occur if the size value is incorrectly specified, and depending upon the value for msgflg (see following section), an error may be generated. The fourth argument, msgtyp , is the type of the message to be retrieved. The message type information is interpreted by the msgrcv system call, as shown in Table 6.12.
Table 6.12. Actions for msgrcv as Indicated by msgtyp Values.
When msgtyp value is |
msgrcv takes this action |
---|---|
Retrieve the first message of any msgtyp . |
|
> 0 |
Retrieve the first message equal to msgtyp if MSG_EXCEPT is not specified. If MSG_EXCEPT is specified, the first message that is not equal to the msgtyp . |
< 0 |
Retrieve the first message of the lowest type less than or equal to absolutevalue of msgtyp . |
Using the type argument judiciously, a user can, with minimal effort, implement a priority-based messaging arrangement whereby the message type indicates its priority.
The fifth and final argument, msgflg , is used to indicate what actions should be taken if a given message type is not in the message queue, or if the message to be retrieved is larger in size than the number of bytes indicated by msgsz . There are three predefined values that msgflg can take. IPC_NOWAIT is used to indicate to msgrcv that it should not block if the requested message type is not in the message queue. If MSG_EXCEPT is specified and the msgtyp value is greater than 0, msgrcv returns the first message not equal to msgtyp . MSG_NOERROR directs msgrcv to silently truncate messages to msgsz bytes if they are found to be too long. If MSG_NOERROR is not specified and msgrcv receives a message that is too long, it returns a -1 and sets the value in errno to E2BIG to indicate the error. In don't-care situations, the value for msgflg can be set to 0. When msgrcv is successful, it returns the number of bytes actually retrieved. See Table 6.13.
Table 6.13. msgrcv Error Messages.
# |
Constant |
perror Message |
Explanation |
---|---|---|---|
4 |
EINTR |
Interrupted system call |
When sleeping on a full message queue, the process received an interrupt. |
7 |
E2BIG |
Argument list too long |
mtext is greater than msgsz and MSG_NOERROR is not specified. |
13 |
EACCES |
Permission denied |
Attempt made to read a message, but the calling process does not have permission. |
14 |
EFAULT |
Bad address |
msgp references a bad address. |
22 |
EINVAL |
Invalid argument |
|
42 |
ENOMSG |
No message of desired type |
Message queue does not have a message of type msgtyp , and IPC_NOWAIT is set. |
43 |
EIDRM |
Identifier removed |
Message queue has been removed. |