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