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