diff options
author | ps <ps@FreeBSD.org> | 2005-10-15 02:54:18 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2005-10-15 02:54:18 +0000 |
commit | c63313b35dc037347e1ede7ea87fa59d5274d48b (patch) | |
tree | 9f9a1f1ea252ef32c27637c08c7252daafe8b1bd /sys | |
parent | a936b63f3d4634b73be4bdb5aa6ab71c17ee1eb9 (diff) | |
download | FreeBSD-src-c63313b35dc037347e1ede7ea87fa59d5274d48b.zip FreeBSD-src-c63313b35dc037347e1ede7ea87fa59d5274d48b.tar.gz |
Implement 32bit wrappers for clock_gettime, clock_settime, and
clock_getres.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 53 | ||||
-rw-r--r-- | sys/compat/freebsd32/syscalls.master | 12 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 70 | ||||
-rw-r--r-- | sys/sys/syscallsubr.h | 6 |
4 files changed, 116 insertions, 25 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 5fcfe58..d3aa4e8 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1260,6 +1260,59 @@ freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) return (error); } +int +freebsd32_clock_gettime(struct thread *td, + struct freebsd32_clock_gettime_args *uap) +{ + struct timespec ats; + struct timespec32 ats32; + int error; + + error = kern_clock_gettime(td, uap->clock_id, &ats); + if (error == 0) { + CP(ats, ats32, tv_sec); + CP(ats, ats32, tv_nsec); + error = copyout(&ats32, uap->tp, sizeof(ats32)); + } + return (error); +} + +int +freebsd32_clock_settime(struct thread *td, + struct freebsd32_clock_settime_args *uap) +{ + struct timespec ats; + struct timespec32 ats32; + int error; + + error = copyin(uap->tp, &ats32, sizeof(ats32)); + if (error) + return (error); + CP(ats32, ats, tv_sec); + CP(ats32, ats, tv_nsec); + + return (kern_clock_settime(td, uap->clock_id, &ats)); +} + +int +freebsd32_clock_getres(struct thread *td, + struct freebsd32_clock_getres_args *uap) +{ + struct timespec ts; + struct timespec32 ts32; + int error; + + if (uap->tp == NULL) + return (0); + error = kern_clock_getres(td, uap->clock_id, &ts); + if (error == 0) { + CP(ts, ts32, tv_sec); + CP(ts, ts32, tv_nsec); + error = copyout(&ts32, uap->tp, sizeof(ts32)); + } + return (error); +} + #if 0 int diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index cab7077..8e6806a 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -412,12 +412,12 @@ 231 AUE_NULL MNOPROTO { int shmget(key_t key, int size, \ int shmflg); } ; -232 AUE_NULL MNOPROTO { int clock_gettime(clockid_t clock_id, \ - struct timespec *tp); } -233 AUE_NULL MNOPROTO { int clock_settime(clockid_t clock_id, \ - const struct timespec *tp); } -234 AUE_NULL MNOPROTO { int clock_getres(clockid_t clock_id, \ - struct timespec *tp); } +232 AUE_NULL MSTD { int freebsd32_clock_gettime(clockid_t clock_id, \ + struct timespec32 *tp); } +233 AUE_NULL MSTD { int freebsd32_clock_settime(clockid_t clock_id, \ + const struct timespec32 *tp); } +234 AUE_NULL MSTD { int freebsd32_clock_getres(clockid_t clock_id, \ + struct timespec32 *tp); } 235 AUE_NULL UNIMPL timer_create 236 AUE_NULL UNIMPL timer_delete 237 AUE_NULL UNIMPL timer_settime diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index d0c3f9e..19d03d1 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -155,34 +155,46 @@ int clock_gettime(struct thread *td, struct clock_gettime_args *uap) { struct timespec ats; + int error; + + error = kern_clock_gettime(td, uap->clock_id, &ats); + if (error == 0) + error = copyout(&ats, uap->tp, sizeof(ats)); + + return (error); +} + +int +kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats) +{ struct timeval sys, user; struct proc *p; p = td->td_proc; - switch (uap->clock_id) { + switch (clock_id) { case CLOCK_REALTIME: - nanotime(&ats); + nanotime(ats); break; case CLOCK_VIRTUAL: PROC_LOCK(p); calcru(p, &user, &sys); PROC_UNLOCK(p); - TIMEVAL_TO_TIMESPEC(&user, &ats); + TIMEVAL_TO_TIMESPEC(&user, ats); break; case CLOCK_PROF: PROC_LOCK(p); calcru(p, &user, &sys); PROC_UNLOCK(p); timevaladd(&user, &sys); - TIMEVAL_TO_TIMESPEC(&user, &ats); + TIMEVAL_TO_TIMESPEC(&user, ats); break; case CLOCK_MONOTONIC: - nanouptime(&ats); + nanouptime(ats); break; default: return (EINVAL); } - return (copyout(&ats, uap->tp, sizeof(ats))); + return (0); } #ifndef _SYS_SYSPROTO_H_ @@ -199,10 +211,20 @@ struct clock_settime_args { int clock_settime(struct thread *td, struct clock_settime_args *uap) { - struct timeval atv; struct timespec ats; int error; + if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) + return (error); + return (kern_clock_settime(td, uap->clock_id, &ats)); +} + +int +kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats) +{ + struct timeval atv; + int error; + #ifdef MAC error = mac_check_system_settime(td->td_ucred); if (error) @@ -210,14 +232,12 @@ clock_settime(struct thread *td, struct clock_settime_args *uap) #endif if ((error = suser(td)) != 0) return (error); - if (uap->clock_id != CLOCK_REALTIME) + if (clock_id != CLOCK_REALTIME) return (EINVAL); - if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) - return (error); - if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) + if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000) return (EINVAL); /* XXX Don't convert nsec->usec and back */ - TIMESPEC_TO_TIMEVAL(&atv, &ats); + TIMESPEC_TO_TIMEVAL(&atv, ats); error = settime(td, &atv); return (error); } @@ -233,9 +253,23 @@ int clock_getres(struct thread *td, struct clock_getres_args *uap) { struct timespec ts; + int error; - ts.tv_sec = 0; - switch (uap->clock_id) { + if (uap->tp == NULL) + return (0); + + error = kern_clock_getres(td, uap->clock_id, &ts); + if (error == 0) + error = copyout(&ts, uap->tp, sizeof(ts)); + return (error); +} + +int +kern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts) +{ + + ts->tv_sec = 0; + switch (clock_id) { case CLOCK_REALTIME: case CLOCK_MONOTONIC: /* @@ -243,19 +277,17 @@ clock_getres(struct thread *td, struct clock_getres_args *uap) * Rounding up is especially important if rounding down * would give 0. Perfect rounding is unimportant. */ - ts.tv_nsec = 1000000000 / tc_getfrequency() + 1; + ts->tv_nsec = 1000000000 / tc_getfrequency() + 1; break; case CLOCK_VIRTUAL: case CLOCK_PROF: /* Accurately round up here because we can do so cheaply. */ - ts.tv_nsec = (1000000000 + hz - 1) / hz; + ts->tv_nsec = (1000000000 + hz - 1) / hz; break; default: return (EINVAL); } - if (uap->tp == NULL) - return (0); - return (copyout(&ts, uap->tp, sizeof(ts))); + return (0); } static int nanowait; diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 75d21e0..d0eec30 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -60,6 +60,12 @@ int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode); int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid); +int kern_clock_getres(struct thread *td, clockid_t clock_id, + struct timespec *ts); +int kern_clock_gettime(struct thread *td, clockid_t clock_id, + struct timespec *ats); +int kern_clock_settime(struct thread *td, clockid_t clock_id, + struct timespec *ats); int kern_connect(struct thread *td, int fd, struct sockaddr *sa); int kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p); |