The semop(2) function performs atomic actions on the
set of semaphores associated with the semaphore associated with
semid. The operations are specified in sops, a
user-defined array of semaphore operation structures (sembuf
structures). The argument nsops specifies the number of
structures in the array.
The structure sembuf contains the following members:
struct sembuf {
unsigned short int sem_num /* semaphore number */
short int sem_op /* semaphore operation */
short int sem_flg /* operation flags */
};
There are really only three semaphore operations (specified by
sem_op although the conditions under which each occurs can
be difficult to understand. The three semaphore operations are:
Reduce the value of semval by the absolute value of
semop.
Return immediately rather than wait for a synchronization
event.
Suspend execution of the process until a synchronization event.
What constitutes a synchronization event depends upon
whether sem_op is positive or negative.
The actual operation performed depends upon the permissions of
the calling process, the value of sem_op the value of
semval (in the sembuf structure), and the value of
sem_flg
semop is negative and the calling process has
alter permission
If semval (from the sembuf structure) is greater
than or equal to the absolute value of sem_op the absolute
value of sem_op is subtracted from semval
The calling process' semadj value may be incremented by
the absolute value of sem_op
If semval is less than the absolute value of
sem_op and (sem_flg & IPC_NOWAIT) is non-zero,
then semop(2) returns immediately.
If semval is less than the absolute value of
sem_op and (sem_flg & IPC_NOWAIT) is 0, semop(2)
increments the semncnt associated with the semaphore and
waits for one of these synchronization events:
The value of semval becomes greater than or equal to the
absolute value of sem_op Then the value of semncnt
associated with the semaphore is decremented, the absolute value of
sem_opsemval and the calling process' semadj
value may be increased by the absolute value of sem_op
The semid is removed from the system. This is an error;
errno is set to [EIDRM] and the function return -1.
The calling process catches a signal. The value of
semncnt associated with the semaphore is decremented and the
calling process resumes execution as described by sigaction(2).
Semop is positive and the calling process has
alter permission
Sem_op is added to semval
The calling process' semadj value may be decreased by the
value of sem_op
Semop is zero and the calling process has read
permission
If semval is non-zero, and (sem_flg &
IPC_NOWAIT) is non-zero, semop(2) returns immediately.
If semval is non-zero and (sem_flg &
IPC_NOWAIT) is 0, semop(2) increments the semzcnt associated
with the semaphore and waits for one of these synchronization
events:
The value of semval is zero; then the value of
semzcnt associated with the semaphore is decremented.
The semid is removed from the system. This is an error;
errno is set to [EIDRM] and the function return -1.
The calling process catches a signal. The value of
semncnt associated with the semaphore is decremented and the
calling process resumes execution as described by sigaction(2).
Some operations adjust the value of semadj a per-process
variable stored in the process table. This happens if
(semflg & SEM_UNDO) is non-zero.
On success, semop(2) returns 0. for each semaphore in the
array pointed to by sops, the value of sempid is set
to the process ID of the calling process.
On failure, semop(2) returns -1 and sets errno to
indicate the error.
The semop(2) call can fail for any of these
reasons:
[E2BIG]
The value of nsops is too large.
[EACCES]
The calling process did not have permission to perform the
operation. Although a semaphore identifier exists for key,
its permissions were not compatible with the low-order 9 bits of
semflg.
[EAGAIN]
Although the call would suspend the calling process, the value
of (sem_flg & IPC_NOWAIT) was non-zero
[EFBIG]
The value of sem_num was outside the range 0 to (number
of semaphores in the set associated with semid-1).
[EIDRM]
The semaphore identifier semid was removed from the
system.
[EINTR]
An interrupt occurred.
[EINVAL]
Semid was not a valid semaphore identifier.
[EINVAL]
The number of semaphores for which the process requested a
SEM_UNDO exceeded the system maximum.
[ENOSPC]
The number of semaphores for which the process requested a
SEM_UNDO exceeded the process maximum.
[ERANGE]
The operation would cause a semval to overflow the
system limit, or the operation would cause a semadj to
overflow the system limit.