summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_time.c
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2009-11-27 19:45:53 +0000
committerguenther <guenther@openbsd.org>2009-11-27 19:45:53 +0000
commitf7123e65102a0fe1394d8065255f50f9361e2bb3 (patch)
tree294717502867640ebf4c89d68c07d814889bd58a /sys/kern/kern_time.c
parentConvert thrsigdivert to (almost) be sigtimedwait by adding siginfo_t (diff)
downloadwireguard-openbsd-f7123e65102a0fe1394d8065255f50f9361e2bb3.tar.xz
wireguard-openbsd-f7123e65102a0fe1394d8065255f50f9361e2bb3.zip
Convert thrsleep() to an absolute timeout with clockid to eliminate a
race condition and prep for later support of pthread_condattr_setclock() "get it in" deraadt@, tedu@, cheers by others
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r--sys/kern/kern_time.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 82a805cffd8..6cb2aa8a320 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.67 2009/10/16 19:29:41 martynas Exp $ */
+/* $OpenBSD: kern_time.c,v 1.68 2009/11/27 19:45:53 guenther Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -156,32 +156,39 @@ settime(struct timespec *ts)
}
#endif
-/* ARGSUSED */
int
-sys_clock_gettime(struct proc *p, void *v, register_t *retval)
+clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp)
{
- struct sys_clock_gettime_args /* {
- syscallarg(clockid_t) clock_id;
- syscallarg(struct timespec *) tp;
- } */ *uap = v;
- clockid_t clock_id;
- struct timespec ats;
-
- clock_id = SCARG(uap, clock_id);
switch (clock_id) {
case CLOCK_REALTIME:
- nanotime(&ats);
+ nanotime(tp);
break;
case CLOCK_MONOTONIC:
- nanouptime(&ats);
+ nanouptime(tp);
break;
case CLOCK_PROF:
- ats.tv_sec = p->p_rtime.tv_sec;
- ats.tv_nsec = p->p_rtime.tv_usec * 1000;
+ tp->tv_sec = p->p_rtime.tv_sec;
+ tp->tv_nsec = p->p_rtime.tv_usec * 1000;
break;
default:
return (EINVAL);
}
+ return (0);
+}
+
+/* ARGSUSED */
+int
+sys_clock_gettime(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_clock_gettime_args /* {
+ syscallarg(clockid_t) clock_id;
+ syscallarg(struct timespec *) tp;
+ } */ *uap = v;
+ struct timespec ats;
+ int error;
+
+ if ((error = clock_gettime(p, SCARG(uap, clock_id), &ats)) != 0)
+ return (error);
return copyout(&ats, SCARG(uap, tp), sizeof(ats));
}
@@ -688,6 +695,18 @@ realitexpire(void *arg)
}
/*
+ * Check that a timespec value is legit
+ */
+int
+timespecfix(struct timespec *ts)
+{
+ if (ts->tv_sec < 0 || ts->tv_sec > 100000000 ||
+ ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000)
+ return (EINVAL);
+ return (0);
+}
+
+/*
* Check that a proposed value to load into the .it_value or
* .it_interval part of an interval timer is acceptable.
*/