summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/adjtime.27
-rw-r--r--sys/kern/kern_time.c40
2 files changed, 32 insertions, 15 deletions
diff --git a/lib/libc/sys/adjtime.2 b/lib/libc/sys/adjtime.2
index ec1196129af..ed0fc358745 100644
--- a/lib/libc/sys/adjtime.2
+++ b/lib/libc/sys/adjtime.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: adjtime.2,v 1.17 2007/05/31 19:19:32 jmc Exp $
+.\" $OpenBSD: adjtime.2,v 1.18 2009/06/05 15:17:02 ckuethe Exp $
.\" $NetBSD: adjtime.2,v 1.5 1995/10/12 15:40:44 jtc Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)adjtime.2 8.1 (Berkeley) 6/4/93
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: June 5 2009 $
.Dt ADJTIME 2
.Os
.Sh NAME
@@ -67,6 +67,9 @@ If
.Fa olddelta
is non-null, the structure pointed to will contain, upon return, the
number of microseconds still to be corrected from the earlier call.
+Setting the time with
+.Xr settimeofday 2
+will cancel any in-progress time adjustment.
.Pp
This call may be used by time servers that synchronize the clocks
of computers in a local area network.
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 2f407187375..cbf0c4e27f5 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.65 2008/09/19 23:36:24 djm Exp $ */
+/* $OpenBSD: kern_time.c,v 1.66 2009/06/05 15:17:02 ckuethe Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -66,7 +66,7 @@ int
settime(struct timespec *ts)
{
struct timespec now;
-
+
/*
* Don't allow the time to be set forward so far it will wrap
@@ -319,6 +319,16 @@ sys_gettimeofday(struct proc *p, void *v, register_t *retval)
return (error);
}
+#ifdef __HAVE_TIMECOUNTER
+struct timeval adjtimedelta; /* unapplied time correction */
+#else
+int tickdelta; /* current clock skew, us. per tick */
+long timedelta; /* unapplied time correction, us. */
+long bigadj = 1000000; /* use 10x skew above bigadj us. */
+int64_t ntp_tick_permanent;
+int64_t ntp_tick_acc;
+#endif
+
/* ARGSUSED */
int
sys_settimeofday(struct proc *p, void *v, register_t *retval)
@@ -343,6 +353,20 @@ sys_settimeofday(struct proc *p, void *v, register_t *retval)
if (SCARG(uap, tv)) {
struct timespec ts;
+ /*
+ * Adjtime in progress is meaningless or harmful after
+ * setting the clock. Cancel adjtime and then set new time.
+ */
+#ifdef __HAVE_TIMECOUNTER
+ adjtimedelta.tv_usec = 0;
+ adjtimedelta.tv_sec = 0;
+#else
+ int s = splclock();
+ tickdelta = 0;
+ timedelta = 0;
+ splx(s);
+#endif
+
TIMEVAL_TO_TIMESPEC(&atv, &ts);
if ((error = settime(&ts)) != 0)
return (error);
@@ -352,16 +376,6 @@ sys_settimeofday(struct proc *p, void *v, register_t *retval)
return (0);
}
-#ifdef __HAVE_TIMECOUNTER
-struct timeval adjtimedelta; /* unapplied time correction */
-#else
-int tickdelta; /* current clock skew, us. per tick */
-long timedelta; /* unapplied time correction, us. */
-long bigadj = 1000000; /* use 10x skew above bigadj us. */
-int64_t ntp_tick_permanent;
-int64_t ntp_tick_acc;
-#endif
-
/* ARGSUSED */
int
sys_adjfreq(struct proc *p, void *v, register_t *retval)
@@ -478,7 +492,7 @@ sys_adjtime(struct proc *p, void *v, register_t *retval)
odelta = ndelta;
ndelta += atv.tv_usec;
if (atv.tv_usec > 0 && ndelta <= odelta)
- ndelta = LONG_MAX;
+ ndelta = LONG_MAX;
else if (atv.tv_usec < 0 && ndelta >= odelta)
ndelta = LONG_MIN;
}