Identifier Based Services
Although each IPC service provides a specific type of interprocess communication, the three identifier based services share many similarities. Each service defines a mechanism through which its communications take place. For message queues, that mechanism is a message queue; for semaphore sets, it is a semaphore set; and for shared memory, it is a shared memory segment. These mechanisms are identified by a unique positive integer called, respectively, a message queue identifier (msqid), a semaphore set identifier (semid), and a shared memory identifier (shmid).
Note: Throughout the Interprocess Communication APIs, the term thread is used extensively. This does not mean that IPC objects can be used only between threads within one process, but rather that authorization checks and waits occur for the calling thread within a process.
Associated with each identifier is a data structure that contains state information for the IPC mechanism, as well as ownership and permissions information. The ownership and permissions information is defined in a structure in the <sys/ipc.h> header file as follows:
typedef struct ipc_perm {
uid_t uid; /* Owner's user ID */
gid_t gid; /* Owner's group ID */
uid_t cuid; /* Creator's user ID */
gid_t cgid; /* Creator's group ID */
mode_t mode; /* Access modes */
} ipc_perm_t;
This structure is similar to a file permissions structure, and is initialized by the thread that creates the IPC mechanism. It is then checked by all subsequent IPC operations to determine if the requesting thread has the required permissions to perform the operation.
To get an identifier, a thread must either create a new IPC mechanism or access an existing mechanism. This is done through the msgget(), semget(), shmget(), and shmget64() functions. Each get operation takes as input a key parameter and returns an identifier. Each get operation also takes a flag parameter. This flag parameter contains the IPC permissions for the mechanism as well as bits that determine whether or not a new mechanism is created. The rules for whether a new mechanism is created or an existing one is referred to are as follows:
- Specifying a key of IPC_PRIVATE guarantees a new mechanism is
created.
- Setting the IPC_CREAT bit in the flag parameter creates a new
mechanism for the specified key if one does not already exist. If an
existing mechanism is found, its identifier is returned.
- Setting both IPC_CREAT and IPC_EXCL creates a new mechanism for the specified key only if a mechanism does not already exist. If an existing mechanism is found, an error is returned.
When a message queue, semaphore set, or shared memory segment is created, the thread that creates it determines how it can be accessed. The thread does this by passing mode information in the low-order 9 bits of the flag parameter on the msgget(), semget(), shmget(), or shmget64() function call. This information is used to initialize the mode field in the ipc_perm structure. The values of the bits are given below in hexadecimal notation:
| Bit | Meaning |
|---|---|
| X'0100' | Read by user |
| X'0080' | Write by user |
| X'0020' | Read by group |
| X'0010' | Write by group |
| X'0004' | Read by others |
| X'0002' | Write by others |
Subsequent IPC operations do a permission test on the calling thread before allowing the thread to perform the requested operation. This permission test is done in one of three forms:
- For the msgget(), semget(),
shmget(), or shmget64() calls that are accessing an existing IPC mechanism, the
caller's flag parameter is checked to make sure it does not specify
access bits that are not in the mode field of the existing IPC
mechanism's ipc_perm structure. If the flag parameter does
not contain any bits that are not in the mode field, permission is
granted.
- For most of the other IPC APIs, the effective user ID and effective group
ID of the thread are retrieved, and these values are compared with the data in
the ipc_perm structure as follows:
- If the effective user ID equals either the uid or the
cuid field for the IPC mechanism, and if the appropriate access bit is on
in the mode field (either Read by user or Write by
user, depending on the operation being requested), permission is
granted.
- If the effective group ID equals either the gid or the
cgid field for the IPC mechanism, and if the appropriate access bit is on
in the mode field (either Read by group or Write by
group), permission is granted.
- If none of the above tests are true, and if the appropriate access bit is
on for others (either Read by others or Write by others),
permission is granted.
- If the effective user ID equals either the uid or the
cuid field for the IPC mechanism, and if the appropriate access bit is on
in the mode field (either Read by user or Write by
user, depending on the operation being requested), permission is
granted.
- For the msgctl(), semctl(), shmctl(), or shmctl64() APIs, some values of the cmd parameter require the caller to be the owner or creator of the IPC object, or have appropriate privileges. The values of cmd that this rule applies to depends on the API. This is shown in the API descriptions for msgctl(), semctl(), shmctl(), and shmctl64().
The Identifier Based Services are divided into the following subcategories:
- Message Queue Functions
- Semaphore Set Functions
- Shared Memory Functions
- IPC Key Generation Functions