Implement 32bit wrappers for clock_gettime, clock_settime, and

clock_getres.
This commit is contained in:
ps 2005-10-15 02:54:18 +00:00
parent a936b63f3d
commit c63313b35d
4 changed files with 116 additions and 25 deletions

View File

@ -1260,6 +1260,59 @@ freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
return (error); 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 #if 0
int int

View File

@ -412,12 +412,12 @@
231 AUE_NULL MNOPROTO { int shmget(key_t key, int size, \ 231 AUE_NULL MNOPROTO { int shmget(key_t key, int size, \
int shmflg); } int shmflg); }
; ;
232 AUE_NULL MNOPROTO { int clock_gettime(clockid_t clock_id, \ 232 AUE_NULL MSTD { int freebsd32_clock_gettime(clockid_t clock_id, \
struct timespec *tp); } struct timespec32 *tp); }
233 AUE_NULL MNOPROTO { int clock_settime(clockid_t clock_id, \ 233 AUE_NULL MSTD { int freebsd32_clock_settime(clockid_t clock_id, \
const struct timespec *tp); } const struct timespec32 *tp); }
234 AUE_NULL MNOPROTO { int clock_getres(clockid_t clock_id, \ 234 AUE_NULL MSTD { int freebsd32_clock_getres(clockid_t clock_id, \
struct timespec *tp); } struct timespec32 *tp); }
235 AUE_NULL UNIMPL timer_create 235 AUE_NULL UNIMPL timer_create
236 AUE_NULL UNIMPL timer_delete 236 AUE_NULL UNIMPL timer_delete
237 AUE_NULL UNIMPL timer_settime 237 AUE_NULL UNIMPL timer_settime

View File

@ -155,34 +155,46 @@ int
clock_gettime(struct thread *td, struct clock_gettime_args *uap) clock_gettime(struct thread *td, struct clock_gettime_args *uap)
{ {
struct timespec ats; 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 timeval sys, user;
struct proc *p; struct proc *p;
p = td->td_proc; p = td->td_proc;
switch (uap->clock_id) { switch (clock_id) {
case CLOCK_REALTIME: case CLOCK_REALTIME:
nanotime(&ats); nanotime(ats);
break; break;
case CLOCK_VIRTUAL: case CLOCK_VIRTUAL:
PROC_LOCK(p); PROC_LOCK(p);
calcru(p, &user, &sys); calcru(p, &user, &sys);
PROC_UNLOCK(p); PROC_UNLOCK(p);
TIMEVAL_TO_TIMESPEC(&user, &ats); TIMEVAL_TO_TIMESPEC(&user, ats);
break; break;
case CLOCK_PROF: case CLOCK_PROF:
PROC_LOCK(p); PROC_LOCK(p);
calcru(p, &user, &sys); calcru(p, &user, &sys);
PROC_UNLOCK(p); PROC_UNLOCK(p);
timevaladd(&user, &sys); timevaladd(&user, &sys);
TIMEVAL_TO_TIMESPEC(&user, &ats); TIMEVAL_TO_TIMESPEC(&user, ats);
break; break;
case CLOCK_MONOTONIC: case CLOCK_MONOTONIC:
nanouptime(&ats); nanouptime(ats);
break; break;
default: default:
return (EINVAL); return (EINVAL);
} }
return (copyout(&ats, uap->tp, sizeof(ats))); return (0);
} }
#ifndef _SYS_SYSPROTO_H_ #ifndef _SYS_SYSPROTO_H_
@ -199,10 +211,20 @@ struct clock_settime_args {
int int
clock_settime(struct thread *td, struct clock_settime_args *uap) clock_settime(struct thread *td, struct clock_settime_args *uap)
{ {
struct timeval atv;
struct timespec ats; struct timespec ats;
int error; 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 #ifdef MAC
error = mac_check_system_settime(td->td_ucred); error = mac_check_system_settime(td->td_ucred);
if (error) if (error)
@ -210,14 +232,12 @@ clock_settime(struct thread *td, struct clock_settime_args *uap)
#endif #endif
if ((error = suser(td)) != 0) if ((error = suser(td)) != 0)
return (error); return (error);
if (uap->clock_id != CLOCK_REALTIME) if (clock_id != CLOCK_REALTIME)
return (EINVAL); return (EINVAL);
if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000)
return (error);
if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
return (EINVAL); return (EINVAL);
/* XXX Don't convert nsec->usec and back */ /* XXX Don't convert nsec->usec and back */
TIMESPEC_TO_TIMEVAL(&atv, &ats); TIMESPEC_TO_TIMEVAL(&atv, ats);
error = settime(td, &atv); error = settime(td, &atv);
return (error); return (error);
} }
@ -233,9 +253,23 @@ int
clock_getres(struct thread *td, struct clock_getres_args *uap) clock_getres(struct thread *td, struct clock_getres_args *uap)
{ {
struct timespec ts; struct timespec ts;
int error;
ts.tv_sec = 0; if (uap->tp == NULL)
switch (uap->clock_id) { 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_REALTIME:
case CLOCK_MONOTONIC: 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 * Rounding up is especially important if rounding down
* would give 0. Perfect rounding is unimportant. * would give 0. Perfect rounding is unimportant.
*/ */
ts.tv_nsec = 1000000000 / tc_getfrequency() + 1; ts->tv_nsec = 1000000000 / tc_getfrequency() + 1;
break; break;
case CLOCK_VIRTUAL: case CLOCK_VIRTUAL:
case CLOCK_PROF: case CLOCK_PROF:
/* Accurately round up here because we can do so cheaply. */ /* 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; break;
default: default:
return (EINVAL); return (EINVAL);
} }
if (uap->tp == NULL) return (0);
return (0);
return (copyout(&ts, uap->tp, sizeof(ts)));
} }
static int nanowait; static int nanowait;

View File

@ -60,6 +60,12 @@ int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg,
int mode); int mode);
int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
int gid); 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_connect(struct thread *td, int fd, struct sockaddr *sa);
int kern_execve(struct thread *td, struct image_args *args, int kern_execve(struct thread *td, struct image_args *args,
struct mac *mac_p); struct mac *mac_p);