2 * Copyright (c) 2000-2001, 2005, 2008 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
11 SM_RCSID("@(#)$Id: sem.c,v 1.14 2008/05/30 16:26:38 ca Exp $")
16 # include <sm/string.h>
22 ** SM_SEM_START -- initialize semaphores
25 ** key -- key for semaphores.
26 ** nsem -- number of semaphores.
27 ** semflg -- flag for semget(), if 0, use a default.
28 ** owner -- create semaphores.
36 sm_sem_start(key
, nsem
, semflg
, owner
)
43 unsigned short *semvals
;
47 semflg
= (SEM_A
|SEM_R
)|((SEM_A
|SEM_R
) >> 3);
49 semflg
|= IPC_CREAT
|IPC_EXCL
;
50 semid
= semget(key
, nsem
, semflg
);
58 semvals
= (unsigned short *) sm_malloc(nsem
* sizeof semvals
);
61 semarg
.array
= semvals
;
63 /* initialize semaphore values to be available */
64 for (i
= 0; i
< nsem
; i
++)
66 if (semctl(semid
, 0, SETALL
, semarg
) < 0)
77 return (err
> 0) ? (0 - err
) : -1;
81 ** SM_SEM_STOP -- stop using semaphores.
84 ** semid -- id for semaphores.
95 return semctl(semid
, 0, IPC_RMID
, NULL
);
99 ** SM_SEM_ACQ -- acquire semaphore.
102 ** semid -- id for semaphores.
103 ** semnum -- number of semaphore.
104 ** timeout -- how long to wait for operation to succeed.
112 sm_sem_acq(semid
, semnum
, timeout
)
118 struct sembuf semops
[1];
120 semops
[0].sem_num
= semnum
;
121 semops
[0].sem_op
= -1;
122 semops
[0].sem_flg
= SEM_UNDO
|
123 (timeout
!= SM_TIME_FOREVER
? 0 : IPC_NOWAIT
);
124 if (timeout
== SM_TIME_IMMEDIATE
|| timeout
== SM_TIME_FOREVER
)
125 return semop(semid
, semops
, 1);
128 r
= semop(semid
, semops
, 1);
133 } while (timeout
> 0);
138 ** SM_SEM_REL -- release semaphore.
141 ** semid -- id for semaphores.
142 ** semnum -- number of semaphore.
143 ** timeout -- how long to wait for operation to succeed.
151 sm_sem_rel(semid
, semnum
, timeout
)
157 struct sembuf semops
[1];
160 /* XXX should we check whether the value is already 0 ? */
161 SM_REQUIRE(sm_get_sem(semid
, semnum
) > 0);
162 #endif /* PARANOID */
164 semops
[0].sem_num
= semnum
;
165 semops
[0].sem_op
= 1;
166 semops
[0].sem_flg
= SEM_UNDO
|
167 (timeout
!= SM_TIME_FOREVER
? 0 : IPC_NOWAIT
);
168 if (timeout
== SM_TIME_IMMEDIATE
|| timeout
== SM_TIME_FOREVER
)
169 return semop(semid
, semops
, 1);
172 r
= semop(semid
, semops
, 1);
177 } while (timeout
> 0);
182 ** SM_SEM_GET -- get semaphore value.
185 ** semid -- id for semaphores.
186 ** semnum -- number of semaphore.
189 ** value of semaphore on success.
194 sm_sem_get(semid
, semnum
)
200 if ((semval
= semctl(semid
, semnum
, GETVAL
, NULL
)) < 0)
206 ** SM_SEMSETOWNER -- set owner/group/mode of semaphores.
209 ** semid -- id for semaphores.
212 ** mode -- mode to use
220 sm_semsetowner(semid
, uid
, gid
, mode
)
227 struct semid_ds semidds
;
230 struct semid_ds
*buf
;
234 memset(&semidds
, 0, sizeof(semidds
));
236 if ((r
= semctl(semid
, 1, IPC_STAT
, arg
)) < 0)
238 semidds
.sem_perm
.uid
= uid
;
239 semidds
.sem_perm
.gid
= gid
;
240 semidds
.sem_perm
.mode
= mode
;
241 if ((r
= semctl(semid
, 1, IPC_SET
, arg
)) < 0)
245 #endif /* SM_CONF_SEM */