Page MenuHomeFreeBSD

D35121.diff
No OneTemporary

D35121.diff

diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -1097,11 +1097,18 @@
#endif
int
sys_semop(struct thread *td, struct semop_args *uap)
+{
+
+ return (kern_semop(td, uap->semid, uap->sops, uap->nsops, NULL));
+}
+
+int
+kern_semop(struct thread *td, int usemid, struct sembuf *usops,
+ size_t nsops, struct timespec *timeout)
{
#define SMALL_SOPS 8
struct sembuf small_sops[SMALL_SOPS];
- int semid = uap->semid;
- size_t nsops = uap->nsops;
+ int semid;
struct prison *rpr;
struct sembuf *sops;
struct semid_kernel *semakptr;
@@ -1109,6 +1116,7 @@
struct sem *semptr = NULL;
struct sem_undo *suptr;
struct mtx *sema_mtxp;
+ sbintime_t sbt, precision;
size_t i, j, k;
int error;
int do_wakeup, do_undos;
@@ -1117,18 +1125,35 @@
#ifdef SEM_DEBUG
sops = NULL;
#endif
- DPRINTF(("call to semop(%d, %p, %u)\n", semid, sops, nsops));
+ DPRINTF(("call to semop(%d, %p, %u)\n", usemid, usops, nsops));
- AUDIT_ARG_SVIPC_ID(semid);
+ AUDIT_ARG_SVIPC_ID(usemid);
rpr = sem_find_prison(td->td_ucred);
if (sem == NULL)
return (ENOSYS);
- semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
+ semid = IPCID_TO_IX(usemid); /* Convert back to zero origin */
if (semid < 0 || semid >= seminfo.semmni)
return (EINVAL);
+ if (timeout != NULL) {
+ if (!timespecvalid_interval(timeout))
+ return (EINVAL);
+ precision = 0;
+ if (timespecisset(timeout)) {
+ if (timeout->tv_sec < INT32_MAX / 2) {
+ precision = tstosbt(*timeout);
+ if (TIMESEL(&sbt, precision))
+ sbt += tc_tick_sbt;
+ sbt += precision;
+ precision >>= tc_precexp;
+ } else
+ sbt = 0;
+ } else
+ sbt = -1;
+ } else
+ precision = sbt = 0;
/* Allocate memory for sem_ops */
if (nsops <= SMALL_SOPS)
@@ -1152,9 +1177,9 @@
sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
}
- if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) {
+ if ((error = copyin(usops, sops, nsops * sizeof(sops[0]))) != 0) {
DPRINTF(("error = %d from copyin(%p, %p, %d)\n", error,
- uap->sops, sops, nsops * sizeof(sops[0])));
+ usops, sops, nsops * sizeof(sops[0])));
if (sops != small_sops)
free(sops, M_TEMP);
return (error);
@@ -1168,7 +1193,7 @@
goto done2;
}
seq = semakptr->u.sem_perm.seq;
- if (seq != IPCID_TO_SEQ(uap->semid)) {
+ if (seq != IPCID_TO_SEQ(usemid)) {
error = EINVAL;
goto done2;
}
@@ -1286,8 +1311,8 @@
semptr->semncnt++;
DPRINTF(("semop: good night!\n"));
- error = msleep(semakptr, sema_mtxp, (PZERO - 4) | PCATCH,
- "semwait", 0);
+ error = msleep_sbt(semakptr, sema_mtxp, (PZERO - 4) | PCATCH,
+ "semwait", sbt, precision, C_ABSOLUTE);
DPRINTF(("semop: good morning (error=%d)!\n", error));
/* return code is checked below, after sem[nz]cnt-- */
@@ -1296,7 +1321,7 @@
*/
seq = semakptr->u.sem_perm.seq;
if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
- seq != IPCID_TO_SEQ(uap->semid)) {
+ seq != IPCID_TO_SEQ(usemid)) {
error = EIDRM;
goto done2;
}
@@ -1323,7 +1348,8 @@
* need to decrement sem[nz]cnt either way.)
*/
if (error != 0) {
- error = EINTR;
+ if (error == ERESTART)
+ error = EINTR;
goto done2;
}
DPRINTF(("semop: good morning!\n"));
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -57,6 +57,7 @@
struct rlimit;
struct rusage;
struct sched_param;
+struct sembuf;
union semun;
struct sockaddr;
struct spacectl_range;
@@ -328,6 +329,8 @@
int kern_ktimer_gettime(struct thread *td, int timer_id,
struct itimerspec *val);
int kern_ktimer_getoverrun(struct thread *td, int timer_id);
+int kern_semop(struct thread *td, int usemid, struct sembuf *usops,
+ size_t nsops, struct timespec *timeout);
int kern_thr_alloc(struct proc *, int pages, struct thread **);
int kern_thr_exit(struct thread *td);
int kern_thr_new(struct thread *td, struct thr_param *param);

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 19, 2:49 PM (21 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14718391
Default Alt Text
D35121.diff (3 KB)

Event Timeline