xref: /csrg-svn/sys/kern/kern_time.c (revision 8103)
1 /*	kern_time.c	5.4	82/09/06	*/
2 
3 #include "../h/param.h"
4 #include "../h/dir.h"		/* XXX */
5 #include "../h/user.h"
6 #include "../h/kernel.h"
7 #include "../h/reg.h"
8 #include "../h/inode.h"
9 #include "../h/proc.h"
10 
11 /*
12  * Time of day and interval timer support.
13  */
14 
15 gettimeofday()
16 {
17 	register struct a {
18 		struct	timeval *tp;
19 		struct	timezone *tzp;
20 	} *uap = (struct a *)u.u_ap;
21 	struct timeval atv;
22 	int s;
23 
24 	s = spl7(); atv = time; splx(s);
25 	if (copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv))) {
26 		u.u_error = EFAULT;
27 		return;
28 	}
29 	if (uap->tzp == 0)
30 		return;
31 	/* SHOULD HAVE PER-PROCESS TIMEZONE */
32 	if (copyout((caddr_t)&tz, uap->tzp, sizeof (tz))) {
33 		u.u_error = EFAULT;
34 		return;
35 	}
36 }
37 
38 settimeofday()
39 {
40 	register struct a {
41 		struct	timeval *tv;
42 		struct	timezone *tzp;
43 	} *uap = (struct a *)u.u_ap;
44 	struct timeval atv;
45 	struct timezone atz;
46 
47 	if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (struct timeval))) {
48 		u.u_error = EFAULT;
49 		return;
50 	}
51 	setthetime(&atv);
52 	if (uap->tzp && suser()) {
53 		if (copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof (atz))) {
54 			u.u_error = EFAULT;
55 			return;
56 		}
57 	}
58 }
59 
60 setthetime(tv)
61 	struct timeval *tv;
62 {
63 	register int delta;
64 	int s;
65 
66 	if (!suser())
67 		return;
68 	boottime.tv_sec += tv->tv_sec - time.tv_sec;
69 	s = spl7(); time = *tv; splx(s);
70 	clockset();
71 }
72 
73 timevaladd(t1, t2)
74 	struct timeval *t1, *t2;
75 {
76 
77 	t1->tv_sec += t2->tv_sec;
78 	t1->tv_usec += t2->tv_usec;
79 	timevalfix(t1);
80 }
81 
82 timevalsub(t1, t2)
83 	struct timeval *t1, *t2;
84 {
85 
86 	t1->tv_sec -= t2->tv_sec;
87 	t1->tv_usec -= t2->tv_usec;
88 	timevalfix(t1);
89 }
90 
91 timevalfix(t1)
92 	struct timeval *t1;
93 {
94 
95 	if (t1->tv_usec < 0) {
96 		t1->tv_sec--;
97 		t1->tv_usec += 1000000;
98 	}
99 	if (t1->tv_usec >= 1000000) {
100 		t1->tv_sec++;
101 		t1->tv_usec -= 1000000;
102 	}
103 }
104 
105 getitimer()
106 {
107 	register struct a {
108 		u_int	which;
109 		struct	itimerval *itv;
110 	} *uap = (struct a *)u.u_ap;
111 	register struct itimerval *itp;
112 	int s;
113 
114 	if (uap->which > 2) {
115 		u.u_error = EINVAL;
116 		return;
117 	}
118 	if (uap->which == ITIMER_REAL)
119 		itp = &u.u_procp->p_realtimer;
120 	else
121 		itp = &u.u_timer[uap->which];
122 	s = spl7();
123 	if (copyout((caddr_t)itp, uap->itv, sizeof (struct itimerval)))
124 		u.u_error = EFAULT;
125 	splx(s);
126 }
127 
128 setitimer()
129 {
130 	register struct a {
131 		u_int	which;
132 		struct	itimerval *itv, *oitv;
133 	} *uap = (struct a *)u.u_ap;
134 	struct itimerval aitv;
135 	int s;
136 
137 	if (uap->which > 2) {
138 		u.u_error = EINVAL;
139 		return;
140 	}
141 	if (copyin((caddr_t)uap->itv, (caddr_t)&aitv,
142 	    sizeof (struct itimerval))) {
143 		u.u_error = EFAULT;
144 		return;
145 	}
146 	if (uap->oitv) {
147 		uap->itv = uap->oitv;
148 		getitimer();
149 	}
150 	if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) {
151 		u.u_error = EINVAL;
152 		return;
153 	}
154 	s = spl7();
155 	if (uap->which == ITIMER_REAL)
156 		u.u_procp->p_realtimer = aitv;
157 	else
158 		u.u_timer[uap->which] = aitv;
159 	splx(s);
160 }
161 
162 itimerfix(tv)
163 	struct timeval *tv;
164 {
165 
166 	if (tv->tv_sec < 0 || tv->tv_usec < 0)
167 		return (EINVAL);
168 	if (tv->tv_sec == 0 && tv->tv_usec < tick)
169 		tv->tv_usec = tick;
170 	return (0);
171 }
172 
173 itimerdecr(itp, usec)
174 	register struct itimerval *itp;
175 	int usec;
176 {
177 
178 	if (itp->it_value.tv_usec < usec) {
179 		if (itp->it_value.tv_sec == 0) {
180 			usec -= itp->it_value.tv_usec;
181 			goto expire;
182 		}
183 		itp->it_value.tv_usec += 1000000;
184 		itp->it_value.tv_sec--;
185 	}
186 	itp->it_value.tv_usec -= usec;
187 	usec = 0;
188 	if (timerisset(&itp->it_value))
189 		return (1);
190 expire:
191 	if (timerisset(&itp->it_interval)) {
192 		itp->it_value = itp->it_interval;
193 		itp->it_value.tv_usec -= usec;
194 		if (itp->it_value.tv_usec < 0) {
195 			itp->it_value.tv_usec += 1000000;
196 			itp->it_value.tv_sec--;
197 		}
198 	} else
199 		itp->it_value.tv_usec = 0;
200 	return (0);
201 }
202 
203 #ifndef NOCOMPAT
204 otime()
205 {
206 
207 	u.u_r.r_time = time.tv_sec;
208 }
209 
210 ostime()
211 {
212 	register struct a {
213 		int	time;
214 	} *uap = (struct a *)u.u_ap;
215 	struct timeval tv;
216 
217 	tv.tv_sec = uap->time;
218 	tv.tv_usec = 0;
219 	setthetime(&tv);
220 }
221 
222 #include "../h/timeb.h"
223 
224 oftime()
225 {
226 	register struct a {
227 		struct	timeb	*tp;
228 	} *uap;
229 	struct timeb t;
230 
231 	uap = (struct a *)u.u_ap;
232 	(void) spl7();
233 	t.time = time.tv_sec;
234 	t.millitm = time.tv_usec / 1000;
235 	(void) spl0();
236 	t.timezone = tz.tz_minuteswest;
237 	t.dstflag = tz.tz_dsttime;
238 	if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t)) < 0)
239 		u.u_error = EFAULT;
240 }
241 #endif
242