diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 8383eae..2f8979b 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -67,10 +67,9 @@ struct timezone tz; * timers when they expire. */ -static int nanosleep1 (struct timespec *rqt, - struct timespec *rmt); -static int settime (struct timeval *); -static void timevalfix (struct timeval *); +static int nanosleep1(struct timespec *rqt, struct timespec *rmt); +static int settime(struct timeval *); +static void timevalfix(struct timeval *); static int sleep_hard_us = 100; SYSCTL_INT(_kern, OID_AUTO, sleep_hard_us, CTLFLAG_RW, &sleep_hard_us, 0, "") @@ -140,56 +139,71 @@ settime(struct timeval *tv) return (0); } -/* ARGSUSED */ int -sys_clock_gettime(struct clock_gettime_args *uap) +kern_clock_gettime(clockid_t clock_id, struct timespec *ats) { - struct timespec ats; - - switch(uap->clock_id) { + switch(clock_id) { case CLOCK_REALTIME: - nanotime(&ats); - return (copyout(&ats, uap->tp, sizeof(ats))); + nanotime(ats); case CLOCK_MONOTONIC: - nanouptime(&ats); - return (copyout(&ats, uap->tp, sizeof(ats))); + nanouptime(ats); default: return (EINVAL); } + + return (0); } /* ARGSUSED */ int -sys_clock_settime(struct clock_settime_args *uap) +sys_clock_gettime(struct clock_gettime_args *uap) +{ + struct timespec ats; + int error; + + error = kern_clock_gettime(uap->clock_id, &ats); + if (error == 0) + error = copyout(&ats, uap->tp, sizeof(ats)) + + return (error); +} + +int +kern_clock_settime(clockid_t clock_id, struct timespec *ats) { struct thread *td = curthread; struct timeval atv; - struct timespec ats; int error; if ((error = priv_check(td, PRIV_ROOT)) != 0) return (error); - switch(uap->clock_id) { - case CLOCK_REALTIME: - if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) - return (error); - if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) - return (EINVAL); - /* XXX Don't convert nsec->usec and back */ - TIMESPEC_TO_TIMEVAL(&atv, &ats); - error = settime(&atv); - return (error); - default: + if (clock_id != CLOCK_REALTIME) return (EINVAL); - } + if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000) + return (EINVAL); + + TIMESPEC_TO_TIMEVAL(&atv, ats); + error = settime(&atv); + return (error); } +/* ARGSUSED */ int -sys_clock_getres(struct clock_getres_args *uap) +sys_clock_settime(struct clock_settime_args *uap) { - struct timespec ts; + struct timespec ats; + int error; + + if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) + return (error); + + return (kern_clock_settime(uap->clock_id, &ats)); +} - switch(uap->clock_id) { +int +kern_clock_getres(clockid_t clock_id, struct timespec *ts) +{ + switch(clock_id) { case CLOCK_REALTIME: case CLOCK_MONOTONIC: /* @@ -198,12 +212,26 @@ sys_clock_getres(struct clock_getres_args *uap) * if rounding down would give 0. Perfect rounding * is unimportant. */ - ts.tv_sec = 0; - ts.tv_nsec = 1000000000 / sys_cputimer->freq + 1; - return(copyout(&ts, uap->tp, sizeof(ts))); + ts->tv_sec = 0; + ts->tv_nsec = 1000000000 / sys_cputimer->freq + 1; default: return(EINVAL); } + + return (0); +} + +int +sys_clock_getres(struct clock_getres_args *uap) +{ + int error; + struct timespec ts; + + error = kern_clock_getres(uap->clock_id, &ts); + if (error == 0) + error = copyout(&ts, uap->tp, sizeof(ts)); + + return (error); } /* diff --git a/sys/sys/time.h b/sys/sys/time.h index 8531295..88e6ae9 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -226,6 +226,9 @@ time_t get_approximate_time_t(void); void set_timeofday(struct timespec *ts); void kern_adjtime(int64_t, int64_t *); void kern_reladjtime(int64_t); +int kern_clock_gettime(clockid_t, struct timespec *); +int kern_clock_settime(clockid_t, struct timespec *); +int kern_clock_getres(clockid_t, struct timespec *); void timevaladd (struct timeval *, const struct timeval *); void timevalsub (struct timeval *, const struct timeval *); int tvtohz_high (struct timeval *);