xref: /csrg-svn/sys/kern/kern_time.c (revision 8034)
1 /*	kern_time.c	5.3	82/09/04	*/
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 gettimeofday()
12 {
13 	register struct a {
14 		struct	timeval *tp;
15 		struct	timezone *tzp;
16 	} *uap = (struct a *)u.u_ap;
17 	struct timeval atv;
18 
19 	microtime(&atv);
20 	if (copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv))) {
21 		u.u_error = EFAULT;
22 		return;
23 	}
24 	if (uap->tzp == 0)
25 		return;
26 	if (copyout((caddr_t)&tz, uap->tzp, sizeof (tz))) {
27 		u.u_error = EFAULT;
28 		return;
29 	}
30 }
31 
32 settimeofday()
33 {
34 	register struct a {
35 		struct timeval *tv;
36 		struct timezone *tzp;
37 	} *uap = (struct a *)u.u_ap;
38 	struct timeval atv;
39 	struct timezone atz;
40 
41 	if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (struct timeval))) {
42 		u.u_error = EFAULT;
43 		return;
44 	}
45 	if (suser()) {
46 		struct timeval tdelta;
47 
48 		tdelta = atv;
49 
50 		timevalsub(&tdelta, &time);
51 		timevaladd(&boottime, &tdelta);
52 		time = atv;
53 		clockset();
54 	}
55 	if (uap->tzp) {
56 		if (copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof (atz))) {
57 			u.u_error = EFAULT;
58 			return;
59 		}
60 		/* XXX */
61 	}
62 }
63 
64 timevaladd(t1, t2)
65 	struct timeval *t1, *t2;
66 {
67 
68 	t1->tv_sec += t2->tv_sec;
69 	t1->tv_usec += t2->tv_sec;
70 	timevalfix(t1);
71 }
72 
73 timevalsub(t1, t2)
74 	struct timeval *t1, *t2;
75 {
76 
77 	t1->tv_sec -= t2->tv_sec;
78 	t1->tv_usec -= t2->tv_sec;
79 	timevalfix(t1);
80 }
81 
82 timevalfix(t1)
83 	struct timeval *t1;
84 {
85 
86 	if (t1->tv_usec < 0) {
87 		t1->tv_sec--;
88 		t1->tv_usec += 1000000;
89 	}
90 	if (t1->tv_usec >= 1000000) {
91 		t1->tv_sec++;
92 		t1->tv_usec -= 1000000;
93 	}
94 }
95 
96 getitimer()
97 {
98 	register struct a {
99 		u_int	which;
100 		struct	itimerval *itv;
101 	} *uap = (struct a *)u.u_ap;
102 	register struct itimerval *itp;
103 	int s;
104 
105 	if (uap->which > 2) {
106 		u.u_error = EINVAL;
107 		return;
108 	}
109 	if (uap->which == ITIMER_REAL)
110 		itp = &u.u_procp->p_realtimer;
111 	else
112 		itp = &u.u_timer[uap->which];
113 	s = spl7();
114 	if (copyout((caddr_t)itp, uap->itv, sizeof (struct itimerval))) {
115 		u.u_error = EFAULT;
116 		goto bad;
117 	}
118 bad:
119 	splx(s);
120 }
121 
122 setitimer()
123 {
124 	register struct a {
125 		u_int	which;
126 		struct	itimerval *itv;
127 	} *uap = (struct a *)u.u_ap;
128 	struct itimerval aitv;
129 	int s;
130 
131 	s = spl7();
132 	if (uap->which > 2) {
133 		u.u_error = EINVAL;
134 		goto bad;
135 	}
136 	if (copyin((caddr_t)uap->itv, (caddr_t)&aitv,
137 	    sizeof (struct itimerval))) {
138 		u.u_error = EFAULT;
139 		goto bad;
140 	}
141 	u.u_timer[uap->which] = aitv;
142 	if (uap->which == ITIMER_REAL)
143 		u.u_procp->p_realtimer = aitv;
144 bad:
145 	splx(s);
146 	return;
147 }
148 
149 getandsetitimer()
150 {
151 	int s = spl7();
152 
153 	getitimer();
154 	if (u.u_error == 0) {
155 		u.u_ap[1] = u.u_ap[2];
156 		setitimer();
157 	}
158 	splx(s);
159 }
160 
161 itimerdecr(itp, usec)
162 	register struct itimerval *itp;
163 	int usec;
164 {
165 
166 	while (itp->itimer_value.tv_usec < usec) {
167 		if (itp->itimer_value.tv_sec == 0)
168 			goto expire;
169 		itp->itimer_value.tv_usec += 1000000;
170 		itp->itimer_value.tv_sec--;
171 	}
172 	itp->itimer_value.tv_usec -= usec;
173 	if (timerisset(&itp->itimer_value))
174 		return (1);
175 expire:
176 	if (itp->itimer_reload == 0)
177 		itp->itimer_value.tv_usec = 0;
178 	else
179 		itp->itimer_value = itp->itimer_interval;
180 	return (0);
181 }
182 
183 #ifndef NOCOMPAT
184 otime()
185 {
186 
187 	u.u_r.r_time = time.tv_sec;
188 }
189 
190 #include "../h/timeb.h"
191 
192 oftime()
193 {
194 	register struct a {
195 		struct	timeb	*tp;
196 	} *uap;
197 	struct timeb t;
198 
199 	uap = (struct a *)u.u_ap;
200 	(void) spl7();
201 	t.time = time.tv_sec;
202 	t.millitm = time.tv_usec / 1000;
203 	(void) spl0();
204 	t.timezone = tz.tz_minuteswest;
205 	t.dstflag = tz.tz_dsttime;
206 	if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t)) < 0)
207 		u.u_error = EFAULT;
208 }
209