xref: /csrg-svn/sys/kern/kern_time.c (revision 8103)
1*8103Sroot /*	kern_time.c	5.4	82/09/06	*/
27424Sroot 
37424Sroot #include "../h/param.h"
48034Sroot #include "../h/dir.h"		/* XXX */
57424Sroot #include "../h/user.h"
68034Sroot #include "../h/kernel.h"
77424Sroot #include "../h/reg.h"
87424Sroot #include "../h/inode.h"
97424Sroot #include "../h/proc.h"
107424Sroot 
11*8103Sroot /*
12*8103Sroot  * Time of day and interval timer support.
13*8103Sroot  */
14*8103Sroot 
158034Sroot gettimeofday()
167424Sroot {
178034Sroot 	register struct a {
188034Sroot 		struct	timeval *tp;
198034Sroot 		struct	timezone *tzp;
208034Sroot 	} *uap = (struct a *)u.u_ap;
218034Sroot 	struct timeval atv;
22*8103Sroot 	int s;
237500Sroot 
24*8103Sroot 	s = spl7(); atv = time; splx(s);
258034Sroot 	if (copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv))) {
268034Sroot 		u.u_error = EFAULT;
278034Sroot 		return;
288034Sroot 	}
298034Sroot 	if (uap->tzp == 0)
308034Sroot 		return;
31*8103Sroot 	/* SHOULD HAVE PER-PROCESS TIMEZONE */
328034Sroot 	if (copyout((caddr_t)&tz, uap->tzp, sizeof (tz))) {
338034Sroot 		u.u_error = EFAULT;
348034Sroot 		return;
358034Sroot 	}
367500Sroot }
377500Sroot 
388034Sroot settimeofday()
397500Sroot {
408034Sroot 	register struct a {
41*8103Sroot 		struct	timeval *tv;
42*8103Sroot 		struct	timezone *tzp;
438034Sroot 	} *uap = (struct a *)u.u_ap;
448034Sroot 	struct timeval atv;
458034Sroot 	struct timezone atz;
467500Sroot 
478034Sroot 	if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (struct timeval))) {
488034Sroot 		u.u_error = EFAULT;
498034Sroot 		return;
508034Sroot 	}
51*8103Sroot 	setthetime(&atv);
52*8103Sroot 	if (uap->tzp && suser()) {
538034Sroot 		if (copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof (atz))) {
548034Sroot 			u.u_error = EFAULT;
558034Sroot 			return;
568034Sroot 		}
578034Sroot 	}
587500Sroot }
597500Sroot 
60*8103Sroot setthetime(tv)
61*8103Sroot 	struct timeval *tv;
62*8103Sroot {
63*8103Sroot 	register int delta;
64*8103Sroot 	int s;
65*8103Sroot 
66*8103Sroot 	if (!suser())
67*8103Sroot 		return;
68*8103Sroot 	boottime.tv_sec += tv->tv_sec - time.tv_sec;
69*8103Sroot 	s = spl7(); time = *tv; splx(s);
70*8103Sroot 	clockset();
71*8103Sroot }
72*8103Sroot 
738034Sroot timevaladd(t1, t2)
748034Sroot 	struct timeval *t1, *t2;
757500Sroot {
767500Sroot 
778034Sroot 	t1->tv_sec += t2->tv_sec;
78*8103Sroot 	t1->tv_usec += t2->tv_usec;
798034Sroot 	timevalfix(t1);
807500Sroot }
817500Sroot 
828034Sroot timevalsub(t1, t2)
838034Sroot 	struct timeval *t1, *t2;
847500Sroot {
857500Sroot 
868034Sroot 	t1->tv_sec -= t2->tv_sec;
87*8103Sroot 	t1->tv_usec -= t2->tv_usec;
888034Sroot 	timevalfix(t1);
897424Sroot }
907424Sroot 
918034Sroot timevalfix(t1)
928034Sroot 	struct timeval *t1;
937424Sroot {
948034Sroot 
958034Sroot 	if (t1->tv_usec < 0) {
968034Sroot 		t1->tv_sec--;
978034Sroot 		t1->tv_usec += 1000000;
988034Sroot 	}
998034Sroot 	if (t1->tv_usec >= 1000000) {
1008034Sroot 		t1->tv_sec++;
1018034Sroot 		t1->tv_usec -= 1000000;
1028034Sroot 	}
1038034Sroot }
1048034Sroot 
1058034Sroot getitimer()
1068034Sroot {
1077424Sroot 	register struct a {
1088034Sroot 		u_int	which;
1098034Sroot 		struct	itimerval *itv;
1108034Sroot 	} *uap = (struct a *)u.u_ap;
1118034Sroot 	register struct itimerval *itp;
1128034Sroot 	int s;
1137424Sroot 
1148034Sroot 	if (uap->which > 2) {
1158034Sroot 		u.u_error = EINVAL;
1168034Sroot 		return;
1177424Sroot 	}
1188034Sroot 	if (uap->which == ITIMER_REAL)
1198034Sroot 		itp = &u.u_procp->p_realtimer;
1208034Sroot 	else
1218034Sroot 		itp = &u.u_timer[uap->which];
1228034Sroot 	s = spl7();
123*8103Sroot 	if (copyout((caddr_t)itp, uap->itv, sizeof (struct itimerval)))
1247424Sroot 		u.u_error = EFAULT;
1258034Sroot 	splx(s);
1267424Sroot }
1277424Sroot 
1288034Sroot setitimer()
1297424Sroot {
1307424Sroot 	register struct a {
1318034Sroot 		u_int	which;
132*8103Sroot 		struct	itimerval *itv, *oitv;
1338034Sroot 	} *uap = (struct a *)u.u_ap;
1348034Sroot 	struct itimerval aitv;
1358034Sroot 	int s;
1367424Sroot 
1378034Sroot 	if (uap->which > 2) {
1388034Sroot 		u.u_error = EINVAL;
139*8103Sroot 		return;
1407424Sroot 	}
1418034Sroot 	if (copyin((caddr_t)uap->itv, (caddr_t)&aitv,
1428034Sroot 	    sizeof (struct itimerval))) {
1438034Sroot 		u.u_error = EFAULT;
144*8103Sroot 		return;
1458034Sroot 	}
146*8103Sroot 	if (uap->oitv) {
147*8103Sroot 		uap->itv = uap->oitv;
148*8103Sroot 		getitimer();
149*8103Sroot 	}
150*8103Sroot 	if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) {
151*8103Sroot 		u.u_error = EINVAL;
152*8103Sroot 		return;
153*8103Sroot 	}
154*8103Sroot 	s = spl7();
1558034Sroot 	if (uap->which == ITIMER_REAL)
1568034Sroot 		u.u_procp->p_realtimer = aitv;
157*8103Sroot 	else
158*8103Sroot 		u.u_timer[uap->which] = aitv;
1598034Sroot 	splx(s);
1607424Sroot }
1617424Sroot 
162*8103Sroot itimerfix(tv)
163*8103Sroot 	struct timeval *tv;
1647424Sroot {
1658034Sroot 
166*8103Sroot 	if (tv->tv_sec < 0 || tv->tv_usec < 0)
167*8103Sroot 		return (EINVAL);
168*8103Sroot 	if (tv->tv_sec == 0 && tv->tv_usec < tick)
169*8103Sroot 		tv->tv_usec = tick;
170*8103Sroot 	return (0);
1718034Sroot }
1728034Sroot 
1738034Sroot itimerdecr(itp, usec)
1748034Sroot 	register struct itimerval *itp;
1758034Sroot 	int usec;
1768034Sroot {
1778034Sroot 
178*8103Sroot 	if (itp->it_value.tv_usec < usec) {
179*8103Sroot 		if (itp->it_value.tv_sec == 0) {
180*8103Sroot 			usec -= itp->it_value.tv_usec;
1818034Sroot 			goto expire;
182*8103Sroot 		}
183*8103Sroot 		itp->it_value.tv_usec += 1000000;
184*8103Sroot 		itp->it_value.tv_sec--;
1858034Sroot 	}
186*8103Sroot 	itp->it_value.tv_usec -= usec;
187*8103Sroot 	usec = 0;
188*8103Sroot 	if (timerisset(&itp->it_value))
1898034Sroot 		return (1);
1908034Sroot expire:
191*8103Sroot 	if (timerisset(&itp->it_interval)) {
192*8103Sroot 		itp->it_value = itp->it_interval;
193*8103Sroot 		itp->it_value.tv_usec -= usec;
194*8103Sroot 		if (itp->it_value.tv_usec < 0) {
195*8103Sroot 			itp->it_value.tv_usec += 1000000;
196*8103Sroot 			itp->it_value.tv_sec--;
197*8103Sroot 		}
198*8103Sroot 	} else
199*8103Sroot 		itp->it_value.tv_usec = 0;
2008034Sroot 	return (0);
2018034Sroot }
2028034Sroot 
2038034Sroot #ifndef NOCOMPAT
2048034Sroot otime()
2058034Sroot {
2068034Sroot 
2078034Sroot 	u.u_r.r_time = time.tv_sec;
2088034Sroot }
2098034Sroot 
210*8103Sroot ostime()
211*8103Sroot {
212*8103Sroot 	register struct a {
213*8103Sroot 		int	time;
214*8103Sroot 	} *uap = (struct a *)u.u_ap;
215*8103Sroot 	struct timeval tv;
216*8103Sroot 
217*8103Sroot 	tv.tv_sec = uap->time;
218*8103Sroot 	tv.tv_usec = 0;
219*8103Sroot 	setthetime(&tv);
220*8103Sroot }
221*8103Sroot 
2228034Sroot #include "../h/timeb.h"
2238034Sroot 
2248034Sroot oftime()
2258034Sroot {
2267424Sroot 	register struct a {
2278034Sroot 		struct	timeb	*tp;
2287424Sroot 	} *uap;
2298034Sroot 	struct timeb t;
2307424Sroot 
2317424Sroot 	uap = (struct a *)u.u_ap;
2328034Sroot 	(void) spl7();
2338034Sroot 	t.time = time.tv_sec;
2348034Sroot 	t.millitm = time.tv_usec / 1000;
2358034Sroot 	(void) spl0();
2368034Sroot 	t.timezone = tz.tz_minuteswest;
2378034Sroot 	t.dstflag = tz.tz_dsttime;
2388034Sroot 	if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t)) < 0)
2397424Sroot 		u.u_error = EFAULT;
2407424Sroot }
241*8103Sroot #endif
242