+ struct timeval atv;
+ int error = 0;
+
+ if (uap->tp) {
+ microtime(&atv);
+ if (error = copyout((caddr_t)&atv, (caddr_t)uap->tp,
+ sizeof (atv)))
+ RETURN (error);
+ }
+ if (uap->tzp)
+ error = copyout((caddr_t)&tz, (caddr_t)uap->tzp,
+ sizeof (tz));
+ RETURN (error);
+}
+
+settimeofday(p, uap, retval)
+ struct proc *p;
+ struct args {
+ struct timeval *tv;
+ struct timezone *tzp;
+ } *uap;
+ int *retval;
+{
+ struct timeval atv;
+ struct timezone atz;
+ int error, s;
+
+ if (error = suser(u.u_cred, &u.u_acflag))
+ RETURN (error);
+ if (uap->tv) {
+ if (error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
+ sizeof (struct timeval)))
+ RETURN (error);
+ /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
+ boottime.tv_sec += atv.tv_sec - time.tv_sec;
+ s = splhigh(); time = atv; splx(s);
+ resettodr();
+ }
+ if (uap->tzp && (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz,
+ sizeof (atz))) == 0)
+ tz = atz;
+ RETURN (error);
+}
+
+extern int tickadj; /* "standard" clock skew, us./tick */
+int tickdelta; /* current clock skew, us. per tick */
+long timedelta; /* unapplied time correction, us. */
+long bigadj = 1000000; /* use 10x skew above bigadj us. */
+
+/* ARGSUSED */
+adjtime(p, uap, retval)
+ struct proc *p;
+ register struct args {
+ struct timeval *delta;
+ struct timeval *olddelta;
+ } *uap;
+ int *retval;
+{
+ struct timeval atv, oatv;
+ register long ndelta;
+ int s, error;
+
+ if (error = suser(u.u_cred, &u.u_acflag))
+ RETURN (error);
+ if (error =
+ copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof (struct timeval)))
+ RETURN (error);
+ ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
+ if (timedelta == 0)
+ if (ndelta > bigadj)
+ tickdelta = 10 * tickadj;
+ else
+ tickdelta = tickadj;
+ if (ndelta % tickdelta)
+ ndelta = ndelta / tickadj * tickadj;
+
+ s = splclock();
+ if (uap->olddelta) {
+ oatv.tv_sec = timedelta / 1000000;
+ oatv.tv_usec = timedelta % 1000000;
+ }
+ timedelta = ndelta;
+ splx(s);
+
+ if (uap->olddelta)
+ (void) copyout((caddr_t)&oatv, (caddr_t)uap->olddelta,
+ sizeof (struct timeval));
+ RETURN (0);