Implement compat32 wrappers for the ktimer_* syscalls.
Reported, reviewed and tested by: Petr Salinger <Petr.Salinger@seznam.cz> Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
058262c69a
commit
643ee87175
@ -69,6 +69,15 @@ struct timespec32 {
|
||||
CP((src).fld,(dst).fld,tv_nsec); \
|
||||
} while (0)
|
||||
|
||||
struct itimerspec32 {
|
||||
struct timespec32 it_interval;
|
||||
struct timespec32 it_value;
|
||||
};
|
||||
#define ITS_CP(src, dst) do { \
|
||||
TS_CP((src), (dst), it_interval); \
|
||||
TS_CP((src), (dst), it_value); \
|
||||
} while (0)
|
||||
|
||||
struct rusage32 {
|
||||
struct timeval32 ru_utime;
|
||||
struct timeval32 ru_stime;
|
||||
|
@ -2331,6 +2331,70 @@ freebsd32_clock_getres(struct thread *td,
|
||||
return (error);
|
||||
}
|
||||
|
||||
int freebsd32_ktimer_create(struct thread *td,
|
||||
struct freebsd32_ktimer_create_args *uap)
|
||||
{
|
||||
struct sigevent32 ev32;
|
||||
struct sigevent ev, *evp;
|
||||
int error, id;
|
||||
|
||||
if (uap->evp == NULL) {
|
||||
evp = NULL;
|
||||
} else {
|
||||
evp = &ev;
|
||||
error = copyin(uap->evp, &ev32, sizeof(ev32));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
error = convert_sigevent32(&ev32, &ev);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
|
||||
if (error == 0) {
|
||||
error = copyout(&id, uap->timerid, sizeof(int));
|
||||
if (error != 0)
|
||||
kern_ktimer_delete(td, id);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_ktimer_settime(struct thread *td,
|
||||
struct freebsd32_ktimer_settime_args *uap)
|
||||
{
|
||||
struct itimerspec32 val32, oval32;
|
||||
struct itimerspec val, oval, *ovalp;
|
||||
int error;
|
||||
|
||||
error = copyin(uap->value, &val32, sizeof(val32));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
ITS_CP(val32, val);
|
||||
ovalp = uap->ovalue != NULL ? &oval : NULL;
|
||||
error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
|
||||
if (error == 0 && uap->ovalue != NULL) {
|
||||
ITS_CP(oval, oval32);
|
||||
error = copyout(&oval32, uap->ovalue, sizeof(oval32));
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_ktimer_gettime(struct thread *td,
|
||||
struct freebsd32_ktimer_gettime_args *uap)
|
||||
{
|
||||
struct itimerspec32 val32;
|
||||
struct itimerspec val;
|
||||
int error;
|
||||
|
||||
error = kern_ktimer_gettime(td, uap->timerid, &val);
|
||||
if (error == 0) {
|
||||
ITS_CP(val, val32);
|
||||
error = copyout(&val32, uap->value, sizeof(val32));
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_clock_getcpuclockid2(struct thread *td,
|
||||
struct freebsd32_clock_getcpuclockid2_args *uap)
|
||||
|
@ -441,11 +441,17 @@
|
||||
const struct timespec32 *tp); }
|
||||
234 AUE_NULL STD { 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
|
||||
238 AUE_NULL UNIMPL timer_gettime
|
||||
239 AUE_NULL UNIMPL timer_getoverrun
|
||||
235 AUE_NULL STD { int freebsd32_ktimer_create(\
|
||||
clockid_t clock_id, \
|
||||
struct sigevent32 *evp, int *timerid); }
|
||||
236 AUE_NULL NOPROTO { int ktimer_delete(int timerid); }
|
||||
237 AUE_NULL STD { int freebsd32_ktimer_settime(int timerid,\
|
||||
int flags, \
|
||||
const struct itimerspec32 *value, \
|
||||
struct itimerspec32 *ovalue); }
|
||||
238 AUE_NULL STD { int freebsd32_ktimer_gettime(int timerid,\
|
||||
struct itimerspec32 *value); }
|
||||
239 AUE_NULL NOPROTO { int ktimer_getoverrun(int timerid); }
|
||||
240 AUE_NULL STD { int freebsd32_nanosleep( \
|
||||
const struct timespec32 *rqtp, \
|
||||
struct timespec32 *rmtp); }
|
||||
|
@ -98,9 +98,6 @@ static int realtimer_settime(struct itimer *, int,
|
||||
static int realtimer_delete(struct itimer *);
|
||||
static void realtimer_clocktime(clockid_t, struct timespec *);
|
||||
static void realtimer_expire(void *);
|
||||
static int kern_timer_create(struct thread *, clockid_t,
|
||||
struct sigevent *, int *, int);
|
||||
static int kern_timer_delete(struct thread *, int);
|
||||
|
||||
int register_posix_clock(int, struct kclock *);
|
||||
void itimer_fire(struct itimer *it);
|
||||
@ -1067,31 +1064,30 @@ struct ktimer_create_args {
|
||||
int
|
||||
sys_ktimer_create(struct thread *td, struct ktimer_create_args *uap)
|
||||
{
|
||||
struct sigevent *evp1, ev;
|
||||
struct sigevent *evp, ev;
|
||||
int id;
|
||||
int error;
|
||||
|
||||
if (uap->evp != NULL) {
|
||||
if (uap->evp == NULL) {
|
||||
evp = NULL;
|
||||
} else {
|
||||
error = copyin(uap->evp, &ev, sizeof(ev));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
evp1 = &ev;
|
||||
} else
|
||||
evp1 = NULL;
|
||||
|
||||
error = kern_timer_create(td, uap->clock_id, evp1, &id, -1);
|
||||
|
||||
evp = &ev;
|
||||
}
|
||||
error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
|
||||
if (error == 0) {
|
||||
error = copyout(&id, uap->timerid, sizeof(int));
|
||||
if (error != 0)
|
||||
kern_timer_delete(td, id);
|
||||
kern_ktimer_delete(td, id);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
kern_timer_create(struct thread *td, clockid_t clock_id,
|
||||
struct sigevent *evp, int *timerid, int preset_id)
|
||||
int
|
||||
kern_ktimer_create(struct thread *td, clockid_t clock_id, struct sigevent *evp,
|
||||
int *timerid, int preset_id)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct itimer *it;
|
||||
@ -1206,7 +1202,8 @@ struct ktimer_delete_args {
|
||||
int
|
||||
sys_ktimer_delete(struct thread *td, struct ktimer_delete_args *uap)
|
||||
{
|
||||
return (kern_timer_delete(td, uap->timerid));
|
||||
|
||||
return (kern_ktimer_delete(td, uap->timerid));
|
||||
}
|
||||
|
||||
static struct itimer *
|
||||
@ -1228,8 +1225,8 @@ itimer_find(struct proc *p, int timerid)
|
||||
return (it);
|
||||
}
|
||||
|
||||
static int
|
||||
kern_timer_delete(struct thread *td, int timerid)
|
||||
int
|
||||
kern_ktimer_delete(struct thread *td, int timerid)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct itimer *it;
|
||||
@ -1271,35 +1268,40 @@ struct ktimer_settime_args {
|
||||
int
|
||||
sys_ktimer_settime(struct thread *td, struct ktimer_settime_args *uap)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct itimer *it;
|
||||
struct itimerspec val, oval, *ovalp;
|
||||
int error;
|
||||
|
||||
error = copyin(uap->value, &val, sizeof(val));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (uap->ovalue != NULL)
|
||||
ovalp = &oval;
|
||||
else
|
||||
ovalp = NULL;
|
||||
ovalp = uap->ovalue != NULL ? &oval : NULL;
|
||||
error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
|
||||
if (error == 0 && uap->ovalue != NULL)
|
||||
error = copyout(ovalp, uap->ovalue, sizeof(*ovalp));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_ktimer_settime(struct thread *td, int timer_id, int flags,
|
||||
struct itimerspec *val, struct itimerspec *oval)
|
||||
{
|
||||
struct proc *p;
|
||||
struct itimer *it;
|
||||
int error;
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
if (uap->timerid < 3 ||
|
||||
(it = itimer_find(p, uap->timerid)) == NULL) {
|
||||
if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
error = EINVAL;
|
||||
} else {
|
||||
PROC_UNLOCK(p);
|
||||
itimer_enter(it);
|
||||
error = CLOCK_CALL(it->it_clockid, timer_settime,
|
||||
(it, uap->flags, &val, ovalp));
|
||||
error = CLOCK_CALL(it->it_clockid, timer_settime, (it,
|
||||
flags, val, oval));
|
||||
itimer_leave(it);
|
||||
ITIMER_UNLOCK(it);
|
||||
}
|
||||
if (error == 0 && uap->ovalue != NULL)
|
||||
error = copyout(ovalp, uap->ovalue, sizeof(*ovalp));
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1312,26 +1314,34 @@ struct ktimer_gettime_args {
|
||||
int
|
||||
sys_ktimer_gettime(struct thread *td, struct ktimer_gettime_args *uap)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct itimer *it;
|
||||
struct itimerspec val;
|
||||
int error;
|
||||
|
||||
error = kern_ktimer_gettime(td, uap->timerid, &val);
|
||||
if (error == 0)
|
||||
error = copyout(&val, uap->value, sizeof(val));
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *val)
|
||||
{
|
||||
struct proc *p;
|
||||
struct itimer *it;
|
||||
int error;
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
if (uap->timerid < 3 ||
|
||||
(it = itimer_find(p, uap->timerid)) == NULL) {
|
||||
if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
error = EINVAL;
|
||||
} else {
|
||||
PROC_UNLOCK(p);
|
||||
itimer_enter(it);
|
||||
error = CLOCK_CALL(it->it_clockid, timer_gettime,
|
||||
(it, &val));
|
||||
error = CLOCK_CALL(it->it_clockid, timer_gettime, (it, val));
|
||||
itimer_leave(it);
|
||||
ITIMER_UNLOCK(it);
|
||||
}
|
||||
if (error == 0)
|
||||
error = copyout(&val, uap->value, sizeof(val));
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1626,7 +1636,7 @@ itimers_event_hook_exit(void *arg, struct proc *p)
|
||||
panic("unhandled event");
|
||||
for (; i < TIMER_MAX; ++i) {
|
||||
if ((it = its->its_timers[i]) != NULL)
|
||||
kern_timer_delete(curthread, i);
|
||||
kern_ktimer_delete(curthread, i);
|
||||
}
|
||||
if (its->its_timers[0] == NULL &&
|
||||
its->its_timers[1] == NULL &&
|
||||
|
@ -228,6 +228,13 @@ int kern_symlink(struct thread *td, char *path, char *link,
|
||||
enum uio_seg segflg);
|
||||
int kern_symlinkat(struct thread *td, char *path1, int fd, char *path2,
|
||||
enum uio_seg segflg);
|
||||
int kern_ktimer_create(struct thread *td, clockid_t clock_id,
|
||||
struct sigevent *evp, int *timerid, int preset_id);
|
||||
int kern_ktimer_delete(struct thread *, int);
|
||||
int kern_ktimer_settime(struct thread *td, int timer_id, int flags,
|
||||
struct itimerspec *val, struct itimerspec *oval);
|
||||
int kern_ktimer_gettime(struct thread *td, int timer_id,
|
||||
struct itimerspec *val);
|
||||
int kern_thr_new(struct thread *td, struct thr_param *param);
|
||||
int kern_thr_suspend(struct thread *td, struct timespec *tsp);
|
||||
int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
|
Loading…
x
Reference in New Issue
Block a user