summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-07-21 19:43:52 +0000
committerkib <kib@FreeBSD.org>2013-07-21 19:43:52 +0000
commita7dacef5abe44a69d8f8d3f79d753a984e59c17c (patch)
tree82302b154c4760230b54ab99ddf9e43c17de823d /sys
parente9d8b81db78ac44bc32831cd4227161dafd886bd (diff)
downloadFreeBSD-src-a7dacef5abe44a69d8f8d3f79d753a984e59c17c.zip
FreeBSD-src-a7dacef5abe44a69d8f8d3f79d753a984e59c17c.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/freebsd32/freebsd32.h9
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c64
-rw-r--r--sys/compat/freebsd32/syscalls.master16
-rw-r--r--sys/kern/kern_time.c90
-rw-r--r--sys/sys/syscallsubr.h7
5 files changed, 141 insertions, 45 deletions
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index a95b0e5..9b04965 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -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;
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 13d2bcb..4899e03 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -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)
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index e058f6a..daee72c 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -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); }
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 6b908a0..3aaed60 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -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 &&
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 75278c3..e18c735 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -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,
OpenPOWER on IntegriCloud