Message Queue Control
The ownership and access permissions, established when the message queue was created, can be examined and modified using the msgctl system call (see Table 6.7).
The msgctl system call references the message queue indicated by the msqid argument. The value of the cmd argument is used to indicate the action that msgctl should take. The following defined constants/actions can be specified:
Table 6.7. Summary of the msgget System Call.
Include File(s) |
|
Manual Section |
2 |
|
Summary |
int msgget (int msqid,int cmd, struct msqid_ds *buf); |
|||
Return |
Success |
Failure |
Sets errno |
|
-1 |
Yes |
- IPC_STAT Return the current values for each member of the msqid_ds data structure (remember that this also contains the permission structure). When using the IPC_STAT flag, the user must provide a location to store the returned information. The address of the storage location for the information is passed as the third argument to the msgctl system call. Of course, the calling process must have read-access privileges for the message queue.
- IPC_SET With this flag, the user (creator, owner, or superuser) can modify a limited number of msqid_ds structure member values. The following members can be modified:
msg_perm.uid, msg_perm.gid, msg_perm.mode, and msg_qbytes
Similar to IPC_STAT, the user must first generate a structure of type msqid_ds, modify the appropriate structure members, and then call msgctl with the IPC_SET flag and pass the address of the modified structure. A successful update will also update the msg_ctime member.
- IPC_RMID Immediately removes all associated message queue structures. When specifying IPC_RMID, the third argument to msgctl is not considered and thus may be left out. However, wanting to leave nothing to chance, most programmers enter the third argument as a NULL value cast to be a pointer to an msqid_ds structure.
If the msgctl system call fails, it returns a -1 and sets errno ; otherwise , it returns a 0 indicating success. The value that errno may be assigned when msgctl fails is given in Table 6.8.
Program 6.3 creates a message queue, uses the msgctl system call to obtain the message queue structure information, and displays pertinent data to the screen.
Table 6.8. msgctl Error Messages.
# |
Constant |
perror Message |
Explanation |
---|---|---|---|
1 |
EPERM |
Operation not |
|
13 |
EACCES |
Permission denied |
cmd is IPC_STAT, but operation is forbidden by the current access permissions (i.e., lacks read access). |
14 |
EFAULT |
Bad address |
cmd is set to IPC_SET or IPC_STAT, but buf references a bad address. |
22 |
EINVAL |
Invalid argument |
|
43 |
EIDRM |
Identifier removed |
The message queue was removed. |
75 |
EOVERFLOW |
Value too large for defined data type |
cmd is IPC_STAT and location referenced by buf is too small to hold the uid or gid values. |
Program 6.3 Using msgctl .
File : p6.3.cxx /* Displaying message queue status information */ #include + #include #include #include #include using namespace std; 10 int main( ){ int mid; key_t key; struct msqid_ds buf; <-- 1 + key = ftok(".", 'z'); if ((mid = msgget(key, IPC_CREAT 0660)) == -1) { <-- 2 perror("Queue create"); return 1; 20 } msgctl(mid, IPC_STAT, &buf); cout << "Message Queue *Permission* Structure Information" << endl; cout << "Owner's user ID " << buf.msg_perm.uid << endl; cout << "Owner's group ID " << buf.msg_perm.gid << endl; + cout << "Creator's user ID " << buf.msg_perm.cuid << endl; cout << "Creator's group ID " << buf.msg_perm.cgid << endl; cout << "Access mode in HEX " << hex << buf.msg_perm.mode << endl; cout << " Additional Selected Message Queue Structure Information "; cout << "Current # of bytes on queue " << dec 30 << buf.__msg_cbytes << endl; cout << "Current # of messages on queue " << buf.msg_qnum << endl; cout << "Maximum # of bytes on queue " << buf.msg_qbytes << endl; msgctl(mid, IPC_RMID, (struct msqid_ds *) 0 ); return 0; + }
(1) The structure buf will store the returned information on the message queue.
(2) Generate the message queue.
Run locally, Program 6.3 produces the output shown in Figure 6.6.
Figure 6.6 Output of Program 6.3.
linux$ p6.3 Message Queue *Permission* Structure Information Owner's user ID 500 Owner's group ID 1000 Creator's user ID 500 Creator's group ID 1000 Access mode in HEX 1b0 Additional Selected Message Queue Structure Information Current # of bytes on queue 0 Current # of messages on queue 0 Maximum # of bytes on queue 16384
As shown, when first generated, the creator of the message queue and the owner are the same. If we convert the displayed hexadecimal access mode value to binary:
1B0
16
and examine the lower nine bits of the binary number, we see the access permissions are indeed 0660 as we specified. The value for the maximum number of bytes on the message queue, shown here as 16384, is one of several system-imposed message queue limits. Additional message queue limit information can be found in the header file .
EXERCISE
It is not possible to create and initialize message queue members atomically. Is this a design flaw or a feature? Support your answer with an example. |