- u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
- sizeof (struct timeval));
- if (u.u_error)
- return;
- setthetime(&atv);
- if (uap->tzp && suser()) {
- u.u_error = copyin((caddr_t)uap->tzp, (caddr_t)&atz,
- sizeof (atz));
- if (u.u_error == 0)
- tz = atz;
+ if (error = suser(p->p_ucred, &p->p_acflag))
+ return (error);
+ /* Verify all parameters before changing time. */
+ if (uap->tv &&
+ (error = copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof(atv))))
+ return (error);
+ if (uap->tzp &&
+ (error = copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof(atz))))
+ return (error);
+ if (uap->tv) {
+ /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
+ s = splclock();
+ /* nb. delta.tv_usec may be < 0, but this is OK here */
+ delta.tv_sec = atv.tv_sec - time.tv_sec;
+ delta.tv_usec = atv.tv_usec - time.tv_usec;
+ time = atv;
+ (void) splsoftclock();
+ timevaladd(&boottime, &delta);
+ timevalfix(&boottime);
+ timevaladd(&runtime, &delta);
+ timevalfix(&runtime);
+# ifdef NFS
+ lease_updatetime(delta.tv_sec);
+# endif
+ splx(s);
+ resettodr();