1SEMOP(P)                   POSIX Programmer's Manual                  SEMOP(P)
2
3
4

NAME

6       semop - XSI semaphore operations
7

SYNOPSIS

9       #include <sys/sem.h>
10
11       int semop(int semid, struct sembuf *sops, size_t nsops);
12
13

DESCRIPTION

15       The  semop()  function operates on XSI semaphores (see the Base Defini‐
16       tions volume of IEEE Std 1003.1-2001, Section 4.15, Semaphore).  It  is
17       unspecified  whether  this  function  interoperates  with  the realtime
18       interprocess communication facilities defined in Realtime .
19
20       The semop() function shall perform atomically a user-defined  array  of
21       semaphore operations on the set of semaphores associated with the sema‐
22       phore identifier specified by the argument semid.
23
24       The argument sops is a pointer to a  user-defined  array  of  semaphore
25       operation  structures.  The implementation shall not modify elements of
26       this array unless the application  uses  implementation-defined  exten‐
27       sions.
28
29       The argument nsops is the number of such structures in the array.
30
31       Each structure, sembuf, includes the following members:
32
33                   Member Type  Member Name  Description
34                   short        sem_num      Semaphore number.
35                   short        sem_op       Semaphore operation.
36                   short        sem_flg      Operation flags.
37
38       Each semaphore operation specified by sem_op is performed on the corre‐
39       sponding semaphore specified by semid and sem_num.
40
41       The variable sem_op specifies one of three semaphore operations:
42
43        1. If sem_op is a negative integer and the calling process  has  alter
44           permission, one of the following shall occur:
45
46            * If semval(see <sys/sem.h>) is greater than or equal to the abso‐
47              lute value of sem_op, the absolute value of sem_op is subtracted
48              from semval. Also, if (sem_flg &SEM_UNDO) is non-zero, the abso‐
49              lute value of sem_op shall be  added  to  the  calling  process'
50              semadj value for the specified semaphore.
51
52            * If semval is less than the absolute value of sem_op and (sem_flg
53              &IPC_NOWAIT) is non-zero, semop() shall return immediately.
54
55            * If semval is less than the absolute value of sem_op and (sem_flg
56              &IPC_NOWAIT)  is  0, semop() shall increment the semncnt associ‐
57              ated with the specified semaphore and suspend execution  of  the
58              calling thread until one of the following conditions occurs:
59
60               * The  value  of  semval  becomes  greater than or equal to the
61                 absolute value of sem_op. When this occurs, the value of sem‐
62                 ncnt  associated with the specified semaphore shall be decre‐
63                 mented, the absolute value of sem_op shall be subtracted from
64                 semval  and, if (sem_flg &SEM_UNDO) is non-zero, the absolute
65                 value of sem_op shall be added to the calling process' semadj
66                 value for the specified semaphore.
67
68               * The  semid for which the calling thread is awaiting action is
69                 removed from the system. When this occurs, errno shall be set
70                 equal to [EIDRM] and -1 shall be returned.
71
72               * The  calling  thread  receives a signal that is to be caught.
73                 When this occurs, the value of semncnt  associated  with  the
74                 specified  semaphore  shall  be  decremented, and the calling
75                 thread shall resume execution in  the  manner  prescribed  in
76                 sigaction() .
77
78        2. If  sem_op  is a positive integer and the calling process has alter
79           permission, the value of sem_op shall be added to  semval  and,  if
80           (sem_flg  &SEM_UNDO) is non-zero, the value of sem_op shall be sub‐
81           tracted from the calling process' semadj value  for  the  specified
82           semaphore.
83
84        3. If  sem_op is 0 and the calling process has read permission, one of
85           the following shall occur:
86
87            * If semval is 0, semop() shall return immediately.
88
89            * If semval is non-zero and  (sem_flg  &IPC_NOWAIT)  is  non-zero,
90              semop() shall return immediately.
91
92            * If  semval  is  non-zero and (sem_flg &IPC_NOWAIT) is 0, semop()
93              shall increment the semzcnt associated with the specified  sema‐
94              phore  and  suspend execution of the calling thread until one of
95              the following occurs:
96
97               * The value of semval becomes 0, at which  time  the  value  of
98                 semzcnt  associated  with  the  specified  semaphore shall be
99                 decremented.
100
101               * The semid for which the calling thread is awaiting action  is
102                 removed from the system. When this occurs, errno shall be set
103                 equal to [EIDRM] and -1 shall be returned.
104
105               * The calling thread receives a signal that is  to  be  caught.
106                 When  this  occurs,  the value of semzcnt associated with the
107                 specified semaphore shall be  decremented,  and  the  calling
108                 thread  shall  resume  execution  in the manner prescribed in
109                 sigaction() .
110
111       Upon successful completion, the value  of  sempid  for  each  semaphore
112       specified  in  the  array  pointed to by sops shall be set equal to the
113       process ID of the calling process.
114

RETURN VALUE

116       Upon successful completion, semop() shall return 0; otherwise, it shall
117       return -1 and set errno to indicate the error.
118

ERRORS

120       The semop() function shall fail if:
121
122       E2BIG  The value of nsops is greater than the system-imposed maximum.
123
124       EACCES Operation  permission  is denied to the calling process; see XSI
125              Interprocess Communication .
126
127       EAGAIN The operation would result in suspension of the calling  process
128              but (sem_flg &IPC_NOWAIT) is non-zero.
129
130       EFBIG  The  value of sem_num is less than 0 or greater than or equal to
131              the number of semaphores in the set associated with semid.
132
133       EIDRM  The semaphore identifier semid is removed from the system.
134
135       EINTR  The semop() function was interrupted by a signal.
136
137       EINVAL The value of semid is not a valid semaphore identifier,  or  the
138              number  of  individual  semaphores for which the calling process
139              requests a SEM_UNDO would exceed the system-imposed limit.
140
141       ENOSPC The limit on the number of  individual  processes  requesting  a
142              SEM_UNDO would be exceeded.
143
144       ERANGE An operation would cause a semval to overflow the system-imposed
145              limit, or an operation would cause a semadj  value  to  overflow
146              the system-imposed limit.
147
148
149       The following sections are informative.
150

EXAMPLES

152   Setting Values in Semaphores
153       The  following example sets the values of the two semaphores associated
154       with the semid identifier to the values contained in the sb array.
155
156
157              #include <sys/sem.h>
158              ...
159              int semid;
160              struct sembuf sb[2];
161              int nsops = 2;
162              int result;
163
164
165              /* Adjust value of semaphore in the semaphore array semid. */
166              sb[0].sem_num = 0;
167              sb[0].sem_op = -1;
168              sb[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
169              sb[1].sem_num = 1;
170              sb[1].sem_op =  1;
171              sb[1].sem_flg = 0;
172
173
174              result = semop(semid, sb, nsops);
175
176   Creating a Semaphore Identifier
177       The following example gets a unique  semaphore  key  using  the  ftok()
178       function,  then  gets a semaphore ID associated with that key using the
179       semget() function (the first call also tests to make sure the semaphore
180       exists).  If  the  semaphore does not exist, the program creates it, as
181       shown by the second call to semget(). In creating the semaphore for the
182       queuing  process,  the  program  attempts  to create one semaphore with
183       read/write permission for all.  It also uses the IPC_EXCL  flag,  which
184       forces semget() to fail if the semaphore already exists.
185
186       After  creating  the  semaphore,  the program uses a call to semop() to
187       initialize it to the values in the sbuf array.  The number of processes
188       that  can  execute  concurrently without queuing is initially set to 2.
189       The final call to semget() creates a semaphore identifier that  can  be
190       used later in the program.
191
192       The  final call to semop() acquires the semaphore and waits until it is
193       free; the SEM_UNDO option  releases  the  semaphore  when  the  process
194       exits,  waiting until there are less than two processes running concur‐
195       rently.
196
197
198              #include <sys/types.h>
199              #include <stdio.h>
200              #include <sys/ipc.h>
201              #include <sys/sem.h>
202              #include <sys/stat.h>
203              #include <errno.h>
204              #include <unistd.h>
205              #include <stdlib.h>
206              #include <pwd.h>
207              #include <fcntl.h>
208              #include <limits.h>
209              ...
210              key_t semkey;
211              int semid, pfd, fv;
212              struct sembuf sbuf;
213              char *lgn;
214              char filename[PATH_MAX+1];
215              struct stat outstat;
216              struct passwd *pw;
217              ...
218              /* Get unique key for semaphore. */
219              if ((semkey = ftok("/tmp", 'a')) == (key_t) -1) {
220                  perror("IPC error: ftok"); exit(1);
221              }
222
223
224              /* Get semaphore ID associated with this key. */
225              if ((semid = semget(semkey, 0, 0)) == -1) {
226
227
228                  /* Semaphore does not exist - Create. */
229                  if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR |
230                      S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1)
231                  {
232                      /* Initialize the semaphore. */
233                      sbuf.sem_num = 0;
234                      sbuf.sem_op = 2;  /* This is the number of runs without queuing. */
235                      sbuf.sem_flg = 0;
236                      if (semop(semid, &sbuf, 1) == -1) {
237                          perror("IPC error: semop"); exit(1);
238                      }
239                  }
240                  else if (errno == EEXIST) {
241                      if ((semid = semget(semkey, 0, 0)) == -1) {
242                          perror("IPC error 1: semget"); exit(1);
243                      }
244                  }
245                  else {
246                      perror("IPC error 2: semget"); exit(1);
247                  }
248              }
249              ...
250              sbuf.sem_num = 0;
251              sbuf.sem_op = -1;
252              sbuf.sem_flg = SEM_UNDO;
253              if (semop(semid, &sbuf, 1) == -1) {
254                  perror("IPC Error: semop"); exit(1);
255              }
256

APPLICATION USAGE

258       The POSIX Realtime Extension defines alternative interfaces for  inter‐
259       process  communication.  Application  developers  who  need  to use IPC
260       should design their applications so that modules using the IPC routines
261       described  in  XSI Interprocess Communication can be easily modified to
262       use the alternative interfaces.
263

RATIONALE

265       None.
266

FUTURE DIRECTIONS

268       None.
269

SEE ALSO

271       XSI Interprocess Communication , Realtime , exec() , exit() , fork()  ,
272       semctl()  ,  semget()  , sem_close() , sem_destroy() , sem_getvalue() ,
273       sem_init() , sem_open() , sem_post() , sem_unlink() , sem_wait() ,  the
274       Base   Definitions   volume   of   IEEE Std 1003.1-2001,   <sys/ipc.h>,
275       <sys/sem.h>, <sys/types.h>
276
278       Portions of this text are reprinted and reproduced in  electronic  form
279       from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
280       -- Portable Operating System Interface (POSIX),  The  Open  Group  Base
281       Specifications  Issue  6,  Copyright  (C) 2001-2003 by the Institute of
282       Electrical and Electronics Engineers, Inc and The Open  Group.  In  the
283       event of any discrepancy between this version and the original IEEE and
284       The Open Group Standard, the original IEEE and The Open Group  Standard
285       is  the  referee document. The original Standard can be obtained online
286       at http://www.opengroup.org/unix/online.html .
287
288
289
290IEEE/The Open Group                  2003                             SEMOP(P)
Impressum