threads/180652: compat32 problem in clock_getcpuclockid2
Konstantin Belousov
kostikbel at gmail.com
Sun Jul 21 09:10:03 UTC 2013
The following reply was made to PR threads/180652; it has been noted by GNATS.
From: Konstantin Belousov <kostikbel at gmail.com>
To: Petr Salinger <Petr.Salinger at seznam.cz>
Cc: freebsd-gnats-submit at FreeBSD.org
Subject: Re: threads/180652: compat32 problem in clock_getcpuclockid2
Date: Sun, 21 Jul 2013 12:05:19 +0300
--E6cJGRvJdK5HoYjj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Sun, Jul 21, 2013 at 10:23:54AM +0200, Petr Salinger wrote:
> >> I only tested with adapted tst-timer2.c. I hope you would do the res=
t.
> > I tried. The tst-timer4.c timed out. I will look at it later.
>=20
> There have been two problems:
>=20
> a) sigev_value.sival_ptr have not been copied
> b) the code misshandles timer_create() with NULL struct sigevent
>=20
> With attached patch, it passes our tests.
>=20
> I think, that there is a similar bug in both new
> freebsd32_kmq_notify() and sys_kmq_notify().
> They do not handle NULL in struct sigevent, it might suffice to
>=20
> - return (kern_kmq_notify(td, uap->mqd, &ev));
> + return (kern_kmq_notify(td, uap->mqd, uap->sigev =3D=3D NULL ? NULL : &=
ev));
>=20
> But this seems not be covered by our testsuite.
Thank you.
I mailed you about sival_int earlier. The bugfix for NULL sigev is
applied to both timers and mqueue. I intend to commit the patch below
later today.
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebs=
d32.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)
=20
+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/f=
reebsd32_misc.c
index cfcd83b..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);
}
=20
+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 =3D=3D NULL) {
+ evp =3D NULL;
+ } else {
+ evp =3D &ev;
+ error =3D copyin(uap->evp, &ev32, sizeof(ev32));
+ if (error !=3D 0)
+ return (error);
+ error =3D convert_sigevent32(&ev32, &ev);
+ if (error !=3D 0)
+ return (error);
+ }
+ error =3D kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
+ if (error =3D=3D 0) {
+ error =3D copyout(&id, uap->timerid, sizeof(int));
+ if (error !=3D 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 =3D copyin(uap->value, &val32, sizeof(val32));
+ if (error !=3D 0)
+ return (error);
+ ITS_CP(val32, val);
+ ovalp =3D uap->ovalue !=3D NULL ? &oval : NULL;
+ error =3D kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
+ if (error =3D=3D 0 && uap->ovalue !=3D NULL) {
+ ITS_CP(oval, oval32);
+ error =3D 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 =3D kern_ktimer_gettime(td, uap->timerid, &val);
+ if (error =3D=3D 0) {
+ ITS_CP(val, val32);
+ error =3D copyout(&val32, uap->value, sizeof(val32));
+ }
+ return (error);
+}
+
int
freebsd32_clock_getcpuclockid2(struct thread *td,
struct freebsd32_clock_getcpuclockid2_args *uap)
@@ -2410,7 +2474,7 @@ siginfo_to_siginfo32(const siginfo_t *src, struct sig=
info32 *dst)
dst->si_uid =3D src->si_uid;
dst->si_status =3D src->si_status;
dst->si_addr =3D (uintptr_t)src->si_addr;
- dst->si_value.sigval_int =3D src->si_value.sival_int;
+ dst->si_value.sival_int =3D src->si_value.sival_int;
dst->si_timerid =3D src->si_timerid;
dst->si_overrun =3D src->si_overrun;
}
@@ -2912,3 +2976,29 @@ freebsd32_posix_fadvise(struct thread *td,
return (kern_posix_fadvise(td, uap->fd, PAIR32TO64(off_t, uap->offset),
PAIR32TO64(off_t, uap->len), uap->advice));
}
+
+int
+convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
+{
+
+ CP(*sig32, *sig, sigev_notify);
+ switch (sig->sigev_notify) {
+ case SIGEV_NONE:
+ break;
+ case SIGEV_THREAD_ID:
+ CP(*sig32, *sig, sigev_notify_thread_id);
+ /* FALLTHROUGH */
+ case SIGEV_SIGNAL:
+ CP(*sig32, *sig, sigev_signo);
+ PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
+ break;
+ case SIGEV_KEVENT:
+ CP(*sig32, *sig, sigev_notify_kqueue);
+ CP(*sig32, *sig, sigev_notify_kevent_flags);
+ PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
+ break;
+ default:
+ return (EINVAL);
+ }
+ return (0);
+}
diff --git a/sys/compat/freebsd32/freebsd32_signal.h b/sys/compat/freebsd32=
/freebsd32_signal.h
index d31a8ae..18899f8 100644
--- a/sys/compat/freebsd32/freebsd32_signal.h
+++ b/sys/compat/freebsd32/freebsd32_signal.h
@@ -97,6 +97,8 @@ struct sigevent32 {
} _sigev_un;
};
=20
+struct sigevent;
+int convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig);
void siginfo_to_siginfo32(const siginfo_t *src, struct siginfo32 *dst);
=20
#endif /* !_COMPAT_FREEBSD32_SIGNAL_H_ */
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/sy=
scalls.master
index 6cb649f..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); }
@@ -476,7 +482,7 @@
struct aiocb32 *aiocbp); }
257 AUE_NULL NOSTD { int freebsd32_lio_listio(int mode, \
struct aiocb32 * const *acb_list, \
- int nent, struct sigevent *sig); }
+ int nent, struct sigevent32 *sig); }
258 AUE_NULL UNIMPL nosys
259 AUE_NULL UNIMPL nosys
260 AUE_NULL UNIMPL nosys
@@ -825,8 +831,8 @@
const char *msg_ptr, size_t msg_len,\
unsigned msg_prio, \
const struct timespec32 *abs_timeout);}
-461 AUE_NULL NOPROTO|NOSTD { int kmq_notify(int mqd, \
- const struct sigevent *sigev); }
+461 AUE_NULL NOSTD { int freebsd32_kmq_notify(int mqd, \
+ const struct sigevent32 *sigev); }
462 AUE_NULL NOPROTO|NOSTD { int kmq_unlink(const char *path); }
463 AUE_NULL NOPROTO { int abort2(const char *why, int nargs, void **args)=
; }
464 AUE_NULL NOPROTO { int thr_set_name(long id, const char *name); }
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 6b908a0..415188c 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);
=20
int register_posix_clock(int, struct kclock *);
void itimer_fire(struct itimer *it);
@@ -1078,20 +1075,18 @@ sys_ktimer_create(struct thread *td, struct ktimer_=
create_args *uap)
evp1 =3D &ev;
} else
evp1 =3D NULL;
-
- error =3D kern_timer_create(td, uap->clock_id, evp1, &id, -1);
-
+ error =3D kern_ktimer_create(td, uap->clock_id, evp1, &id, -1);
if (error =3D=3D 0) {
error =3D copyout(&id, uap->timerid, sizeof(int));
if (error !=3D 0)
- kern_timer_delete(td, id);
+ kern_ktimer_delete(td, id);
}
return (error);
}
=20
-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 =3D td->td_proc;
struct itimer *it;
@@ -1206,7 +1201,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));
}
=20
static struct itimer *
@@ -1228,8 +1224,8 @@ itimer_find(struct proc *p, int timerid)
return (it);
}
=20
-static int
-kern_timer_delete(struct thread *td, int timerid)
+int
+kern_ktimer_delete(struct thread *td, int timerid)
{
struct proc *p =3D td->td_proc;
struct itimer *it;
@@ -1271,35 +1267,40 @@ struct ktimer_settime_args {
int
sys_ktimer_settime(struct thread *td, struct ktimer_settime_args *uap)
{
- struct proc *p =3D td->td_proc;
- struct itimer *it;
struct itimerspec val, oval, *ovalp;
int error;
=20
error =3D copyin(uap->value, &val, sizeof(val));
if (error !=3D 0)
return (error);
-=09
- if (uap->ovalue !=3D NULL)
- ovalp =3D &oval;
- else
- ovalp =3D NULL;
+ ovalp =3D uap->ovalue !=3D NULL ? &oval : NULL;
+ error =3D kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
+ if (error =3D=3D 0 && uap->ovalue !=3D NULL)
+ error =3D copyout(ovalp, uap->ovalue, sizeof(*ovalp));
+ return (error);
+}
=20
+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 =3D td->td_proc;
PROC_LOCK(p);
- if (uap->timerid < 3 ||
- (it =3D itimer_find(p, uap->timerid)) =3D=3D NULL) {
+ if (timer_id < 3 || (it =3D itimer_find(p, timer_id)) =3D=3D NULL) {
PROC_UNLOCK(p);
error =3D EINVAL;
} else {
PROC_UNLOCK(p);
itimer_enter(it);
- error =3D CLOCK_CALL(it->it_clockid, timer_settime,
- (it, uap->flags, &val, ovalp));
+ error =3D CLOCK_CALL(it->it_clockid, timer_settime, (it,
+ flags, val, oval));
itimer_leave(it);
ITIMER_UNLOCK(it);
}
- if (error =3D=3D 0 && uap->ovalue !=3D NULL)
- error =3D copyout(ovalp, uap->ovalue, sizeof(*ovalp));
return (error);
}
=20
@@ -1312,26 +1313,34 @@ struct ktimer_gettime_args {
int
sys_ktimer_gettime(struct thread *td, struct ktimer_gettime_args *uap)
{
- struct proc *p =3D td->td_proc;
- struct itimer *it;
struct itimerspec val;
int error;
=20
+ error =3D kern_ktimer_gettime(td, uap->timerid, &val);
+ if (error =3D=3D 0)
+ error =3D copyout(&val, uap->value, sizeof(val));
+ return (error);
+}
+
+int
+kern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *va=
l)
+{
+ struct proc *p;
+ struct itimer *it;
+ int error;
+
+ p =3D td->td_proc;
PROC_LOCK(p);
- if (uap->timerid < 3 ||
- (it =3D itimer_find(p, uap->timerid)) =3D=3D NULL) {
+ if (timer_id < 3 || (it =3D itimer_find(p, timer_id)) =3D=3D NULL) {
PROC_UNLOCK(p);
error =3D EINVAL;
} else {
PROC_UNLOCK(p);
itimer_enter(it);
- error =3D CLOCK_CALL(it->it_clockid, timer_gettime,
- (it, &val));
+ error =3D CLOCK_CALL(it->it_clockid, timer_gettime, (it, val));
itimer_leave(it);
ITIMER_UNLOCK(it);
}
- if (error =3D=3D 0)
- error =3D copyout(&val, uap->value, sizeof(val));
return (error);
}
=20
@@ -1626,7 +1635,7 @@ itimers_event_hook_exit(void *arg, struct proc *p)
panic("unhandled event");
for (; i < TIMER_MAX; ++i) {
if ((it =3D its->its_timers[i]) !=3D NULL)
- kern_timer_delete(curthread, i);
+ kern_ktimer_delete(curthread, i);
}
if (its->its_timers[0] =3D=3D NULL &&
its->its_timers[1] =3D=3D NULL &&
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index 73579d3..1439a5d 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -2235,10 +2235,9 @@ sys_kmq_timedsend(struct thread *td, struct kmq_time=
dsend_args *uap)
return (error);
}
=20
-int
-sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
+static int
+kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev)
{
- struct sigevent ev;
struct filedesc *fdp;
struct proc *p;
struct mqueue *mq;
@@ -2246,34 +2245,31 @@ sys_kmq_notify(struct thread *td, struct kmq_notify=
_args *uap)
struct mqueue_notifier *nt, *newnt =3D NULL;
int error;
=20
- p =3D td->td_proc;
- fdp =3D td->td_proc->p_fd;
- if (uap->sigev) {
- error =3D copyin(uap->sigev, &ev, sizeof(ev));
- if (error)
- return (error);
- if (ev.sigev_notify !=3D SIGEV_SIGNAL &&
- ev.sigev_notify !=3D SIGEV_THREAD_ID &&
- ev.sigev_notify !=3D SIGEV_NONE)
+ if (sigev !=3D NULL) {
+ if (sigev->sigev_notify !=3D SIGEV_SIGNAL &&
+ sigev->sigev_notify !=3D SIGEV_THREAD_ID &&
+ sigev->sigev_notify !=3D SIGEV_NONE)
return (EINVAL);
- if ((ev.sigev_notify =3D=3D SIGEV_SIGNAL ||
- ev.sigev_notify =3D=3D SIGEV_THREAD_ID) &&
- !_SIG_VALID(ev.sigev_signo))
+ if ((sigev->sigev_notify =3D=3D SIGEV_SIGNAL ||
+ sigev->sigev_notify =3D=3D SIGEV_THREAD_ID) &&
+ !_SIG_VALID(sigev->sigev_signo))
return (EINVAL);
}
- error =3D getmq(td, uap->mqd, &fp, NULL, &mq);
+ p =3D td->td_proc;
+ fdp =3D td->td_proc->p_fd;
+ error =3D getmq(td, mqd, &fp, NULL, &mq);
if (error)
return (error);
again:
FILEDESC_SLOCK(fdp);
- fp2 =3D fget_locked(fdp, uap->mqd);
+ fp2 =3D fget_locked(fdp, mqd);
if (fp2 =3D=3D NULL) {
FILEDESC_SUNLOCK(fdp);
error =3D EBADF;
goto out;
}
#ifdef CAPABILITIES
- error =3D cap_check(cap_rights(fdp, uap->mqd), CAP_POLL_EVENT);
+ error =3D cap_check(cap_rights(fdp, mqd), CAP_POLL_EVENT);
if (error) {
FILEDESC_SUNLOCK(fdp);
goto out;
@@ -2286,12 +2282,12 @@ again:
}
mtx_lock(&mq->mq_mutex);
FILEDESC_SUNLOCK(fdp);
- if (uap->sigev !=3D NULL) {
+ if (sigev !=3D NULL) {
if (mq->mq_notifier !=3D NULL) {
error =3D EBUSY;
} else {
PROC_LOCK(p);
- nt =3D notifier_search(p, uap->mqd);
+ nt =3D notifier_search(p, mqd);
if (nt =3D=3D NULL) {
if (newnt =3D=3D NULL) {
PROC_UNLOCK(p);
@@ -2314,10 +2310,10 @@ again:
nt->nt_ksi.ksi_flags |=3D KSI_INS | KSI_EXT;
nt->nt_ksi.ksi_code =3D SI_MESGQ;
nt->nt_proc =3D p;
- nt->nt_ksi.ksi_mqd =3D uap->mqd;
+ nt->nt_ksi.ksi_mqd =3D mqd;
notifier_insert(p, nt);
}
- nt->nt_sigev =3D ev;
+ nt->nt_sigev =3D *sigev;
mq->mq_notifier =3D nt;
PROC_UNLOCK(p);
/*
@@ -2330,7 +2326,7 @@ again:
mqueue_send_notification(mq);
}
} else {
- notifier_remove(p, mq, uap->mqd);
+ notifier_remove(p, mq, mqd);
}
mtx_unlock(&mq->mq_mutex);
=20
@@ -2341,6 +2337,20 @@ out:
return (error);
}
=20
+int
+sys_kmq_notify(struct thread *td, struct kmq_notify_args *uap)
+{
+ struct sigevent ev;
+ int error;
+
+ if (uap->sigev !=3D NULL) {
+ error =3D copyin(uap->sigev, &ev, sizeof(ev));
+ if (error !=3D 0)
+ return (error);
+ }
+ return (kern_kmq_notify(td, uap->mqd, &ev));
+}
+
static void
mqueue_fdclose(struct thread *td, int fd, struct file *fp)
{
@@ -2637,6 +2647,7 @@ static struct syscall_helper_data mq_syscalls[] =3D {
#ifdef COMPAT_FREEBSD32
#include <compat/freebsd32/freebsd32.h>
#include <compat/freebsd32/freebsd32_proto.h>
+#include <compat/freebsd32/freebsd32_signal.h>
#include <compat/freebsd32/freebsd32_syscall.h>
#include <compat/freebsd32/freebsd32_util.h>
=20
@@ -2763,12 +2774,33 @@ freebsd32_kmq_timedreceive(struct thread *td,
return (error);
}
=20
+int
+freebsd32_kmq_notify(struct thread *td, struct freebsd32_kmq_notify_args *=
uap)
+{
+ struct sigevent ev, *evp;
+ struct sigevent32 ev32;
+ int error;
+
+ if (uap->sigev =3D=3D NULL) {
+ evp =3D NULL;
+ } else {
+ error =3D copyin(uap->sigev, &ev32, sizeof(ev32));
+ if (error !=3D 0)
+ return (error);
+ error =3D convert_sigevent32(&ev32, &ev);
+ if (error !=3D 0)
+ return (error);
+ evp =3D &ev;
+ }
+ return (kern_kmq_notify(td, uap->mqd, evp));
+}
+
static struct syscall_helper_data mq32_syscalls[] =3D {
SYSCALL32_INIT_HELPER(freebsd32_kmq_open),
SYSCALL32_INIT_HELPER(freebsd32_kmq_setattr),
SYSCALL32_INIT_HELPER(freebsd32_kmq_timedsend),
SYSCALL32_INIT_HELPER(freebsd32_kmq_timedreceive),
- SYSCALL32_INIT_HELPER_COMPAT(kmq_notify),
+ SYSCALL32_INIT_HELPER(freebsd32_kmq_notify),
SYSCALL32_INIT_HELPER_COMPAT(kmq_unlink),
SYSCALL_INIT_LAST
};
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 5fb9341..862443c 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -2755,31 +2755,6 @@ aiocb32_copyin_old_sigevent(struct aiocb *ujob, stru=
ct aiocb *kjob)
}
=20
static int
-convert_sigevent32(struct sigevent32 *sig32, struct sigevent *sig)
-{
-
- CP(*sig32, *sig, sigev_notify);
- switch (sig->sigev_notify) {
- case SIGEV_NONE:
- break;
- case SIGEV_THREAD_ID:
- CP(*sig32, *sig, sigev_notify_thread_id);
- /* FALLTHROUGH */
- case SIGEV_SIGNAL:
- CP(*sig32, *sig, sigev_signo);
- break;
- case SIGEV_KEVENT:
- CP(*sig32, *sig, sigev_notify_kqueue);
- CP(*sig32, *sig, sigev_notify_kevent_flags);
- PTRIN_CP(*sig32, *sig, sigev_value.sival_ptr);
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-static int
aiocb32_copyin(struct aiocb *ujob, struct aiocb *kjob)
{
struct aiocb32 job32;
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,
--E6cJGRvJdK5HoYjj
Content-Type: application/pgp-signature
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (FreeBSD)
iQIcBAEBAgAGBQJR66ROAAoJEJDCuSvBvK1Bl3EP/0DLz7SfXRo4y1ne3u2AJwBv
cFVtAgkB9cxdQJ228A9G0Mwo6iEUAlCbFxloYyVCG2Pyuiil+7SCgQ5+VLIGCkIj
4eF9NANztHTs4S3blm3GwauyeoTQAcfXYFB+GMzxtyfjaKyPPkJ39a7jZRC8e2nK
yI9C9snJIocawaIObg+sMMkJxIpDWJ01sL22NaAgm4udg+OJFiqJVLPaud+PE7oi
jflTZFTpQAlStezpJpjwxp1owNB2jnDcx6wQdbmO280ti9WZNRTFpmT/iV2Ah9ik
QQGQ1AxtfCrMoGcbMdrADKJjq+qLI+OH87tEQZv5bK0vivEPRszTdNMAm5sFsJ+a
8SMiM616hIWSjTbANpb0suIB1AsdFgTMTzE1j7yrZ5bi5GLF9yFE5Fmsi09O3QQB
lkX9Xqvg6Yvw6FRxDhl8DUDyOuxtWE+1eDhtWOBwDaDTocBxL5QnRb7rE3nQbY8v
DQfnfQMy+lk193bpcuXtxjG7cHivaWJ5yKRAktOJuROsrjd05H2vuqiL4D7SC6/5
4cBdjrThoHUpCt4A4QWHygxLZsVTtq+nWZQZpeNmYGoWgy7JMz5xsO3tQMtUCcsR
tg8fad2B8mCn2hbwVhx1YLCI3PVIbsW85NbrznGhcwJY7tsbFohl+UoSVIbqB8z1
p3OJYUG6yMrTJGEZy0ri
=ABIi
-----END PGP SIGNATURE-----
--E6cJGRvJdK5HoYjj--
More information about the freebsd-threads
mailing list