aboutsummaryrefslogtreecommitdiff
path: root/sys/compat
diff options
context:
space:
mode:
authorPaul Saab <ps@FreeBSD.org>2005-03-01 17:45:55 +0000
committerPaul Saab <ps@FreeBSD.org>2005-03-01 17:45:55 +0000
commitb8a4edc17e15250601b4a8e2eede404a004de248 (patch)
tree10558b08e817450d6d38eaa125c3e87ee71d4dc9 /sys/compat
parentc1aa81b6d915d908251c177e5bdbf5608ed6a62d (diff)
downloadsrc-b8a4edc17e15250601b4a8e2eede404a004de248.tar.gz
src-b8a4edc17e15250601b4a8e2eede404a004de248.zip
Use kern_kevent instead of the stackgap for 32bit syscall wrapping.
Submitted by: jhb Tested on: amd64
Notes
Notes: svn path=/head/; revision=142934
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c66
1 files changed, 31 insertions, 35 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 90c23e5ae9ca..68c6ce44156f 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -556,44 +556,34 @@ CTASSERT(sizeof(struct kevent32) == 20);
int
freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
{
- int error;
- caddr_t sg;
struct timespec32 ts32;
- struct timespec ts;
- struct kevent32 ks32;
+ struct timespec ts, *tsp;
struct kevent *ks;
- struct kevent_args a;
- int i;
+ struct kevent32 ks32;
+ struct kevent *changes, *events;
+ int error, i;
- sg = stackgap_init();
-
- a.fd = uap->fd;
- a.changelist = (struct kevent *)uap->changelist;
- a.nchanges = uap->nchanges;
- a.eventlist = (struct kevent *)uap->eventlist;
- a.nevents = uap->nevents;
- a.timeout = NULL;
if (uap->timeout) {
- a.timeout = stackgap_alloc(&sg, sizeof(struct timespec));
error = copyin(uap->timeout, &ts32, sizeof(ts32));
if (error)
return (error);
CP(ts32, ts, tv_sec);
CP(ts32, ts, tv_nsec);
- error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts));
- if (error)
- return (error);
- }
- if (uap->changelist) {
- a.changelist = (struct kevent *)stackgap_alloc(&sg,
- uap->nchanges * sizeof(struct kevent));
+ tsp = &ts;
+ } else
+ tsp = NULL;
+ if (uap->changelist && uap->nchanges > 0) {
+ changes = malloc(sizeof(struct kevent) * uap->nchanges, M_TEMP,
+ M_WAITOK);
for (i = 0; i < uap->nchanges; i++) {
error = copyin(&uap->changelist[i], &ks32,
sizeof(ks32));
- if (error)
+ if (error) {
+ free(changes, M_TEMP);
return (error);
- ks = (struct kevent *)(uintptr_t)&a.changelist[i];
+ }
+ ks = &changes[i];
CP(ks32, *ks, ident);
CP(ks32, *ks, filter);
CP(ks32, *ks, flags);
@@ -601,15 +591,19 @@ freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
CP(ks32, *ks, data);
PTRIN_CP(ks32, *ks, udata);
}
- }
- if (uap->eventlist) {
- a.eventlist = stackgap_alloc(&sg,
- uap->nevents * sizeof(struct kevent));
- }
- error = kevent(td, &a);
- if (uap->eventlist && error > 0) {
- for (i = 0; i < error; i++) {
- ks = &a.eventlist[i];
+ } else
+ changes = NULL;
+ if (uap->eventlist && uap->nevents > 0)
+ events = malloc(sizeof(struct kevent) * uap->nevents, M_TEMP,
+ M_WAITOK);
+ else
+ events = NULL;
+ error = kern_kevent(td, uap->fd, changes, uap->nchanges, UIO_SYSSPACE,
+ events, uap->nevents, UIO_SYSSPACE, tsp);
+ free(changes, M_TEMP);
+ if (uap->eventlist && events && td->td_retval[0] > 0) {
+ for (i = 0; i < td->td_retval[0]; i++) {
+ ks = &events[i];
CP(*ks, ks32, ident);
CP(*ks, ks32, filter);
CP(*ks, ks32, flags);
@@ -619,10 +613,12 @@ freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
error = copyout(&ks32, &uap->eventlist[i],
sizeof(ks32));
if (error)
- return (error);
+ break;
}
}
- return error;
+ if (events)
+ free(events, M_TEMP);
+ return (error);
}
int