summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2020-04-02 07:00:25 +0000
committermpi <mpi@openbsd.org>2020-04-02 07:00:25 +0000
commit2699785b2d538a744d0b5aea0ce92d135e05c36a (patch)
treeb723350068d421f6db867585499c32d754148716
parentEnable FFS2 option for both floppies (diff)
downloadwireguard-openbsd-2699785b2d538a744d0b5aea0ce92d135e05c36a.tar.xz
wireguard-openbsd-2699785b2d538a744d0b5aea0ce92d135e05c36a.zip
Introduce kqueue_sleep() a wrapper around the tsleep(9) dance.
While here check for the validity of the timeout at the begining of the syscall. ok kettenis@, cheloha@
-rw-r--r--sys/kern/kern_event.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index ec7492872a3..8514d92b2c0 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.128 2020/03/20 04:14:50 cheloha Exp $ */
+/* $OpenBSD: kern_event.c,v 1.129 2020/04/02 07:00:25 mpi Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -61,6 +61,7 @@ void kqueue_init(void);
void KQREF(struct kqueue *);
void KQRELE(struct kqueue *);
+int kqueue_sleep(struct kqueue *, struct timespec *);
int kqueue_scan(struct kqueue *kq, int maxevents,
struct kevent *ulistp, struct timespec *timeout,
struct proc *p, int *retval);
@@ -556,6 +557,10 @@ sys_kevent(struct proc *p, void *v, register_t *retval)
error = copyin(SCARG(uap, timeout), &ts, sizeof(ts));
if (error)
goto done;
+ if (ts.tv_sec < 0 || !timespecisvalid(&ts)) {
+ error = EINVAL;
+ goto done;
+ }
#ifdef KTRACE
if (KTRPOINT(p, KTR_STRUCT))
ktrreltimespec(p, &ts);
@@ -838,13 +843,37 @@ done:
}
int
+kqueue_sleep(struct kqueue *kq, struct timespec *tsp)
+{
+ struct timespec elapsed, start, stop;
+ uint64_t nsecs;
+ int error;
+
+ splassert(IPL_HIGH);
+
+ if (tsp != NULL) {
+ getnanouptime(&start);
+ nsecs = MIN(TIMESPEC_TO_NSEC(tsp), MAXTSLP);
+ } else
+ nsecs = INFSLP;
+ error = tsleep_nsec(kq, PSOCK | PCATCH, "kqread", nsecs);
+ if (tsp != NULL) {
+ getnanouptime(&stop);
+ timespecsub(&stop, &start, &elapsed);
+ timespecsub(tsp, &elapsed, tsp);
+ if (tsp->tv_sec < 0)
+ timespecclear(tsp);
+ }
+
+ return (error);
+}
+
+int
kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp,
struct timespec *tsp, struct proc *p, int *retval)
{
struct kevent *kevp;
- struct timespec elapsed, start, stop;
struct knote mend, mstart, *kn;
- uint64_t nsecs;
int s, count, nkev = 0, error = 0;
struct kevent kev[KQ_NEVENTS];
@@ -852,11 +881,6 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *ulistp,
if (count == 0)
goto done;
- if (tsp != NULL && (tsp->tv_sec < 0 || !timespecisvalid(tsp))) {
- error = EINVAL;
- goto done;
- }
-
memset(&mstart, 0, sizeof(mstart));
memset(&mend, 0, sizeof(mend));
@@ -875,19 +899,7 @@ retry:
goto done;
}
kq->kq_state |= KQ_SLEEP;
- if (tsp != NULL) {
- getnanouptime(&start);
- nsecs = MIN(TIMESPEC_TO_NSEC(tsp), MAXTSLP);
- } else
- nsecs = INFSLP;
- error = tsleep_nsec(kq, PSOCK | PCATCH, "kqread", nsecs);
- if (tsp != NULL) {
- getnanouptime(&stop);
- timespecsub(&stop, &start, &elapsed);
- timespecsub(tsp, &elapsed, tsp);
- if (tsp->tv_sec < 0)
- timespecclear(tsp);
- }
+ error = kqueue_sleep(kq, tsp);
splx(s);
if (error == 0 || error == EWOULDBLOCK)
goto retry;