Subject: Re: kevent(2) under COMPAT_NETBSD32
To: Martin Husemann <martin@duskware.de>
From: Quentin Garnier <cube@cubidou.net>
List: tech-kern
Date: 07/15/2005 14:53:56
--sr8SBrQ3fbgntwtR
Content-Type: multipart/mixed; boundary="AHVSF3we4xtO5oi5"
Content-Disposition: inline


--AHVSF3we4xtO5oi5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Jul 13, 2005 at 11:23:52PM +0200, Quentin Garnier wrote:
> On Wed, Jul 13, 2005 at 03:47:02PM +0200, Martin Husemann wrote:
> > On Wed, Jul 13, 2005 at 03:42:05PM +0200, Quentin Garnier wrote:
> > > The only other sane way of having a netbsd32 version of kevent(2) is
> > > through rewriting everything (sys_kevent and kqueue_scan).  I don't
> > > like that solution because with time the native version will change
> > > and the netbsd32 will start being different.
> >=20
> > Can we replace function calls be preproccessor magic, move sys_kevent a=
nd
> > kqueue_scan into a template file - trading code size for runtime?
>=20
> I've just had a peek at the FreeBSD kern_event.c code as it is currently
> in their tree.
>=20
> They basically do the same stuff that I do in my patch, and their code
> points me to a stupid error in mine, which malloc() at each pass of
> netbsd32_kevent_fetch_changes and netbsd32_kevent_put_event.
>=20
> I'll rework that to first allocate the buffer, and then pass a pointer
> to a structure containting the necessary state.

Here's the updated version.

--=20
Quentin Garnier - cube@cubidou.net - cube@NetBSD.org
"When I find the controls, I'll go where I like, I'll know where I want
to be, but maybe for now I'll stay right here on a silent sea."
KT Tunstall, Silent Sea, Eye to the Telescope, 2004.

--AHVSF3we4xtO5oi5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="event.diff"
Content-Transfer-Encoding: quoted-printable

? compat/netbsd32/netbsd32_event.c
Index: kern/kern_event.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/kern_event.c,v
retrieving revision 1.23
diff -u -r1.23 kern_event.c
--- kern/kern_event.c	29 May 2005 22:24:15 -0000	1.23
+++ kern/kern_event.c	15 Jul 2005 12:47:37 -0000
@@ -54,11 +54,11 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
=20
-static int	kqueue_scan(struct file *fp, size_t maxevents,
-		    struct kevent *ulistp, const struct timespec *timeout,
-		    struct proc *p, register_t *retval);
 static void	kqueue_wakeup(struct kqueue *kq);
=20
+static int	kqueue_scan(struct file *, size_t, struct kevent *,
+    const struct timespec *, struct proc *, register_t *,
+    const struct kevent_ops *);
 static int	kqueue_read(struct file *fp, off_t *offset, struct uio *uio,
 		    struct ucred *cred, int flags);
 static int	kqueue_write(struct file *fp, off_t *offset, struct uio *uio,
@@ -629,6 +629,27 @@
 /*
  * kevent(2) system call.
  */
+static int
+kevent_fetch_changes(void *private, const struct kevent *changelist,
+    struct kevent *changes, size_t index, int n)
+{
+	return copyin(changelist + index, changes, n * sizeof(*changes));
+}
+
+static int
+kevent_put_events(void *private, struct kevent *events,
+    struct kevent *eventlist, size_t index, int n)
+{
+	return copyout(events, eventlist + index, n * sizeof(*events));
+}
+
+static const struct kevent_ops kevent_native_ops =3D {
+	keo_private: NULL,
+	keo_fetch_timeout: copyin,
+	keo_fetch_changes: kevent_fetch_changes,
+	keo_put_events: kevent_put_events,
+};
+
 int
 sys_kevent(struct lwp *l, void *v, register_t *retval)
 {
@@ -640,17 +661,29 @@
 		syscallarg(size_t) nevents;
 		syscallarg(const struct timespec *) timeout;
 	} */ *uap =3D v;
+
+	return kevent1(l, retval, SCARG(uap, fd), SCARG(uap, changelist),
+	    SCARG(uap, nchanges), SCARG(uap, eventlist), SCARG(uap, nevents),
+	    SCARG(uap, timeout), &kevent_native_ops);
+}
+
+int
+kevent1(struct lwp *l, register_t *retval, int fd,
+    const struct kevent *changelist, size_t nchanges, struct kevent *event=
list,
+    size_t nevents, const struct timespec *timeout,
+    const struct kevent_ops *keops)
+{
 	struct kevent	*kevp;
 	struct kqueue	*kq;
 	struct file	*fp;
 	struct timespec	ts;
 	struct proc	*p;
-	size_t		i, n;
+	size_t		i, n, ichange;
 	int		nerrors, error;
=20
 	p =3D l->l_proc;
 	/* check that we're dealing with a kq */
-	fp =3D fd_getfile(p->p_fd, SCARG(uap, fd));
+	fp =3D fd_getfile(p->p_fd, fd);
 	if (fp =3D=3D NULL)
 		return (EBADF);
=20
@@ -661,22 +694,23 @@
=20
 	FILE_USE(fp);
=20
-	if (SCARG(uap, timeout) !=3D NULL) {
-		error =3D copyin(SCARG(uap, timeout), &ts, sizeof(ts));
+	if (timeout !=3D NULL) {
+		error =3D (*keops->keo_fetch_timeout)(timeout, &ts, sizeof(ts));
 		if (error)
 			goto done;
-		SCARG(uap, timeout) =3D &ts;
+		timeout =3D &ts;
 	}
=20
 	kq =3D (struct kqueue *)fp->f_data;
 	nerrors =3D 0;
+	ichange =3D 0;
=20
 	/* traverse list of events to register */
-	while (SCARG(uap, nchanges) > 0) {
+	while (nchanges > 0) {
 		/* copyin a maximum of KQ_EVENTS at each pass */
-		n =3D MIN(SCARG(uap, nchanges), KQ_NEVENTS);
-		error =3D copyin(SCARG(uap, changelist), kq->kq_kev,
-		    n * sizeof(struct kevent));
+		n =3D MIN(nchanges, KQ_NEVENTS);
+		error =3D (*keops->keo_fetch_changes)(keops->keo_private,
+		    changelist, kq->kq_kev, ichange, n);
 		if (error)
 			goto done;
 		for (i =3D 0; i < n; i++) {
@@ -685,24 +719,23 @@
 			/* register each knote */
 			error =3D kqueue_register(kq, kevp, p);
 			if (error) {
-				if (SCARG(uap, nevents) !=3D 0) {
+				if (nevents !=3D 0) {
 					kevp->flags =3D EV_ERROR;
 					kevp->data =3D error;
-					error =3D copyout((caddr_t)kevp,
-					    (caddr_t)SCARG(uap, eventlist),
-					    sizeof(*kevp));
+					error =3D (*keops->keo_put_events)
+					    (keops->keo_private, kevp,
+					    eventlist, nerrors, 1);
 					if (error)
 						goto done;
-					SCARG(uap, eventlist)++;
-					SCARG(uap, nevents)--;
+					nevents--;
 					nerrors++;
 				} else {
 					goto done;
 				}
 			}
 		}
-		SCARG(uap, nchanges) -=3D n;	/* update the results */
-		SCARG(uap, changelist) +=3D n;
+		nchanges -=3D n;	/* update the results */
+		ichange +=3D n;
 	}
 	if (nerrors) {
 		*retval =3D nerrors;
@@ -711,8 +744,7 @@
 	}
=20
 	/* actually scan through the events */
-	error =3D kqueue_scan(fp, SCARG(uap, nevents), SCARG(uap, eventlist),
-	    SCARG(uap, timeout), p, retval);
+	error =3D kqueue_scan(fp, nevents, eventlist, timeout, p, retval, keops);
  done:
 	FILE_UNUSE(fp, p);
 	return (error);
@@ -866,18 +898,19 @@
  */
 static int
 kqueue_scan(struct file *fp, size_t maxevents, struct kevent *ulistp,
-	const struct timespec *tsp, struct proc *p, register_t *retval)
+    const struct timespec *tsp, struct proc *p, register_t *retval,
+    const struct kevent_ops *keops)
 {
 	struct kqueue	*kq;
 	struct kevent	*kevp;
 	struct timeval	atv;
 	struct knote	*kn, *marker=3DNULL;
-	size_t		count, nkev;
+	size_t		count, nkev, nevents;
 	int		s, timeout, error;
=20
 	kq =3D (struct kqueue *)fp->f_data;
 	count =3D maxevents;
-	nkev =3D error =3D 0;
+	nkev =3D nevents =3D error =3D 0;
 	if (count =3D=3D 0)
 		goto done;
=20
@@ -996,9 +1029,9 @@
 		if (nkev =3D=3D KQ_NEVENTS) {
 			/* do copyouts in KQ_NEVENTS chunks */
 			splx(s);
-			error =3D copyout((caddr_t)&kq->kq_kev, (caddr_t)ulistp,
-			    sizeof(struct kevent) * nkev);
-			ulistp +=3D nkev;
+			error =3D (*keops->keo_put_events)(keops->keo_private,
+			    &kq->kq_kev[0], ulistp, nevents, nkev);
+			nevents +=3D nkev;
 			nkev =3D 0;
 			kevp =3D kq->kq_kev;
 			s =3D splsched();
@@ -1016,11 +1049,10 @@
 	if (marker)
 		FREE(marker, M_KEVENT);
=20
-	if (nkev !=3D 0) {
+	if (nkev !=3D 0)
 		/* copyout remaining events */
-		error =3D copyout((caddr_t)&kq->kq_kev, (caddr_t)ulistp,
-		    sizeof(struct kevent) * nkev);
-	}
+		error =3D (*keops->keo_put_events)(keops->keo_private,
+		    &kq->kq_kev[0], ulistp, nevents, nkev);
 	*retval =3D maxevents - count;
=20
 	return (error);
Index: sys/systm.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/sys/systm.h,v
retrieving revision 1.179
diff -u -r1.179 systm.h
--- sys/systm.h	23 Jun 2005 00:30:28 -0000	1.179
+++ sys/systm.h	15 Jul 2005 12:47:38 -0000
@@ -240,6 +240,10 @@
 int	copyin(const void *, void *, size_t);
 int	copyout(const void *, void *, size_t);
=20
+#ifdef _KERNEL
+typedef	int (*copyinout_t)(const void *, void *, size_t);
+#endif /* _KERNEL */
+
 int	copyin_proc(struct proc *, const void *, void *, size_t);
 int	copyout_proc(struct proc *, const void *, void *, size_t);
=20
Index: sys/event.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/sys/event.h,v
retrieving revision 1.15
diff -u -r1.15 event.h
--- sys/event.h	26 Feb 2005 22:25:34 -0000	1.15
+++ sys/event.h	15 Jul 2005 12:47:38 -0000
@@ -198,13 +198,32 @@
 #define	kn_fp		kn_ptr.p_fp
 };
=20
+#include <sys/systm.h> /* for copyinout_t */
+
 struct proc;
+struct timespec;
=20
 void	knote(struct klist *, long);
 void	knote_remove(struct proc *, struct klist *);
 void	knote_fdclose(struct proc *, int);
 int 	kqueue_register(struct kqueue *, struct kevent *, struct proc *);
=20
+typedef	int (*kevent_fetch_changes_t)(void *, const struct kevent *,
+    struct kevent *, size_t, int);
+typedef	int (*kevent_put_events_t)(void *, struct kevent *, struct kevent =
*,
+    size_t, int);
+
+struct kevent_ops {
+	void *keo_private;
+	copyinout_t keo_fetch_timeout;
+	kevent_fetch_changes_t keo_fetch_changes;
+	kevent_put_events_t keo_put_events;
+};
+
+int	kevent1(struct lwp *, register_t *, int, const struct kevent *,
+    size_t, struct kevent *, size_t, const struct timespec *,
+    const struct kevent_ops *);
+
 int	kfilter_register(const char *, const struct filterops *, int *);
 int	kfilter_unregister(const char *);
=20
Index: compat/netbsd32/files.netbsd32
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/files.netbsd32,v
retrieving revision 1.17
diff -u -r1.17 files.netbsd32
--- compat/netbsd32/files.netbsd32	17 Jun 2004 18:29:40 -0000	1.17
+++ compat/netbsd32/files.netbsd32	15 Jul 2005 12:47:38 -0000
@@ -10,6 +10,7 @@
 file	compat/netbsd32/netbsd32_exec_elf32.c	compat_netbsd32 & exec_elf32
 file	compat/netbsd32/netbsd32_exec_aout.c	compat_netbsd32 & exec_aout
 file	compat/netbsd32/netbsd32_netbsd.c	compat_netbsd32
+file	compat/netbsd32/netbsd32_event.c	compat_netbsd32
 file	compat/netbsd32/netbsd32_execve.c	compat_netbsd32
 file	compat/netbsd32/netbsd32_fs.c		compat_netbsd32
 file	compat/netbsd32/netbsd32_ioctl.c	compat_netbsd32
Index: compat/netbsd32/netbsd32.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32.h,v
retrieving revision 1.35
diff -u -r1.35 netbsd32.h
--- compat/netbsd32/netbsd32.h	13 Jul 2005 11:53:57 -0000	1.35
+++ compat/netbsd32/netbsd32.h	15 Jul 2005 12:47:38 -0000
@@ -559,6 +559,18 @@
 /* from <sys/uuid.h> */
 typedef netbsd32_pointer_t netbsd32_uuidp_t;
=20
+/* from <sys/event.h> */
+typedef netbsd32_pointer_t netbsd32_keventp_t;
+
+struct netbsd32_kevent {
+	netbsd32_uintptr_t	ident;
+	uint32_t		filter;
+	uint32_t		flags;
+	uint32_t		fflags;
+	int64_t			data;
+	netbsd32_intptr_t	udata;
+} __attribute__((packed));
+
 void netbsd32_si_to_si32(siginfo32_t *, const siginfo_t *);
 void netbsd32_si32_to_si(siginfo_t *, const siginfo32_t *);
=20
Index: compat/netbsd32/netbsd32_conv.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_conv.h,v
retrieving revision 1.5
diff -u -r1.5 netbsd32_conv.h
--- compat/netbsd32/netbsd32_conv.h	26 Feb 2005 23:10:21 -0000	1.5
+++ compat/netbsd32/netbsd32_conv.h	15 Jul 2005 12:47:38 -0000
@@ -50,6 +50,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/timex.h>
+#include <sys/event.h>
=20
 #include <compat/netbsd32/netbsd32.h>
=20
@@ -79,6 +80,8 @@
 static __inline void netbsd32_to_semid_ds __P((struct  netbsd32_semid_ds *=
, struct  semid_ds *));
 static __inline void netbsd32_from_semid_ds __P((struct  semid_ds *, struc=
t  netbsd32_semid_ds *));
 static __inline void netbsd32_from_loadavg __P((struct netbsd32_loadavg *,=
 struct loadavg *));
+static __inline void netbsd32_to_kevent(struct netbsd32_kevent *, struct k=
event *);
+static __inline void netbsd32_from_kevent(struct kevent *, struct netbsd32=
_kevent *);
=20
 /* converters for structures that we need */
 static __inline void
@@ -535,4 +538,26 @@
 	av32->fscale =3D (netbsd32_long)av->fscale;
 }
=20
+static __inline void
+netbsd32_to_kevent(struct netbsd32_kevent *ke32, struct kevent *ke)
+{
+	ke->ident =3D ke32->ident;
+	ke->filter =3D ke32->filter;
+	ke->flags =3D ke32->flags;
+	ke->fflags =3D ke32->fflags;
+	ke->data =3D ke32->data;
+	ke->udata =3D ke32->udata;
+}
+
+static __inline void
+netbsd32_from_kevent(struct kevent *ke, struct netbsd32_kevent *ke32)
+{
+	ke32->ident =3D ke->ident;
+	ke32->filter =3D ke->filter;
+	ke32->flags =3D ke->flags;
+	ke32->fflags =3D ke->fflags;
+	ke32->data =3D ke->data;
+	ke32->udata =3D ke->udata;
+}
+
 #endif /* _COMPAT_NETBSD32_NETBSD32_CONV_H_ */
Index: compat/netbsd32/netbsd32_syscall.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_syscall.h,v
retrieving revision 1.42
diff -u -r1.42 netbsd32_syscall.h
--- compat/netbsd32/netbsd32_syscall.h	12 Jul 2005 07:46:19 -0000	1.42
+++ compat/netbsd32/netbsd32_syscall.h	15 Jul 2005 12:47:39 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_syscall.h,v 1.42 2005/07/12 07:46:19 cube Exp $ */
+/* $NetBSD$ */
=20
 /*
  * System call numbers.
@@ -842,6 +842,12 @@
 /* syscall: "netbsd32_rasctl" ret: "int" args: "netbsd32_caddr_t" "netbsd3=
2_size_t" "int" */
 #define	netbsd32_SYS_netbsd32_rasctl	343
=20
+/* syscall: "kqueue" ret: "int" args: */
+#define	netbsd32_SYS_kqueue	344
+
+/* syscall: "netbsd32_kevent" ret: "int" args: "int" "netbsd32_keventp_t" =
"netbsd32_size_t" "netbsd32_keventp_t" "netbsd32_size_t" "netbsd32_timespec=
p_t" */
+#define	netbsd32_SYS_netbsd32_kevent	345
+
 /* syscall: "netbsd32_fsync_range" ret: "int" args: "int" "int" "off_t" "o=
ff_t" */
 #define	netbsd32_SYS_netbsd32_fsync_range	354
=20
Index: compat/netbsd32/netbsd32_syscallargs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_syscallargs.h,v
retrieving revision 1.42
diff -u -r1.42 netbsd32_syscallargs.h
--- compat/netbsd32/netbsd32_syscallargs.h	12 Jul 2005 07:46:19 -0000	1.42
+++ compat/netbsd32/netbsd32_syscallargs.h	15 Jul 2005 12:47:40 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_syscallargs.h,v 1.42 2005/07/12 07:46:19 cube Exp $ */
+/* $NetBSD$ */
=20
 /*
  * System call argument lists.
@@ -1298,6 +1298,15 @@
 	syscallarg(int) op;
 };
=20
+struct netbsd32_kevent_args {
+	syscallarg(int) fd;
+	syscallarg(netbsd32_keventp_t) changelist;
+	syscallarg(netbsd32_size_t) nchanges;
+	syscallarg(netbsd32_keventp_t) eventlist;
+	syscallarg(netbsd32_size_t) nevents;
+	syscallarg(netbsd32_timespecp_t) timeout;
+};
+
 struct netbsd32_fsync_range_args {
 	syscallarg(int) fd;
 	syscallarg(int) flags;
@@ -2067,6 +2076,10 @@
=20
 int	netbsd32_rasctl(struct lwp *, void *, register_t *);
=20
+int	sys_kqueue(struct lwp *, void *, register_t *);
+
+int	netbsd32_kevent(struct lwp *, void *, register_t *);
+
 int	netbsd32_fsync_range(struct lwp *, void *, register_t *);
=20
 int	netbsd32_uuidgen(struct lwp *, void *, register_t *);
Index: compat/netbsd32/netbsd32_syscalls.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_syscalls.c,v
retrieving revision 1.42
diff -u -r1.42 netbsd32_syscalls.c
--- compat/netbsd32/netbsd32_syscalls.c	12 Jul 2005 07:46:19 -0000	1.42
+++ compat/netbsd32/netbsd32_syscalls.c	15 Jul 2005 12:47:40 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_syscalls.c,v 1.42 2005/07/12 07:46:19 cube Exp $ */
+/* $NetBSD$ */
=20
 /*
  * System call names.
@@ -8,7 +8,7 @@
  */
=20
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_syscalls.c,v 1.42 2005/07/12 07:46:19=
 cube Exp $");
+__KERNEL_RCSID(0, "$NetBSD$");
=20
 #if defined(_KERNEL_OPT)
 #if defined(_KERNEL_OPT)
@@ -470,8 +470,8 @@
 	"#341 (unimplemented)",		/* 341 =3D unimplemented */
 	"#342 (unimplemented)",		/* 342 =3D unimplemented */
 	"netbsd32_rasctl",			/* 343 =3D netbsd32_rasctl */
-	"#344 (unimplemented)",		/* 344 =3D unimplemented */
-	"#345 (unimplemented)",		/* 345 =3D unimplemented */
+	"kqueue",			/* 344 =3D kqueue */
+	"netbsd32_kevent",			/* 345 =3D netbsd32_kevent */
 	"#346 (unimplemented)",		/* 346 =3D unimplemented */
 	"#347 (unimplemented)",		/* 347 =3D unimplemented */
 	"#348 (unimplemented)",		/* 348 =3D unimplemented */
Index: compat/netbsd32/netbsd32_sysent.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_sysent.c,v
retrieving revision 1.42
diff -u -r1.42 netbsd32_sysent.c
--- compat/netbsd32/netbsd32_sysent.c	12 Jul 2005 07:46:19 -0000	1.42
+++ compat/netbsd32/netbsd32_sysent.c	15 Jul 2005 12:47:41 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_sysent.c,v 1.42 2005/07/12 07:46:19 cube Exp $ */
+/* $NetBSD$ */
=20
 /*
  * System call switch table.
@@ -8,7 +8,7 @@
  */
=20
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.42 2005/07/12 07:46:19 c=
ube Exp $");
+__KERNEL_RCSID(0, "$NetBSD$");
=20
 #if defined(_KERNEL_OPT)
 #include "opt_ktrace.h"
@@ -915,9 +915,9 @@
 	{ 3, s(struct netbsd32_rasctl_args), 0,
 	    netbsd32_rasctl },			/* 343 =3D netbsd32_rasctl */
 	{ 0, 0, 0,
-	    sys_nosys },			/* 344 =3D unimplemented */
-	{ 0, 0, 0,
-	    sys_nosys },			/* 345 =3D unimplemented */
+	    sys_kqueue },			/* 344 =3D kqueue */
+	{ 6, s(struct netbsd32_kevent_args), 0,
+	    netbsd32_kevent },			/* 345 =3D netbsd32_kevent */
 	{ 0, 0, 0,
 	    sys_nosys },			/* 346 =3D unimplemented */
 	{ 0, 0, 0,
Index: compat/netbsd32/syscalls.master
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/compat/netbsd32/syscalls.master,v
retrieving revision 1.35
diff -u -r1.35 syscalls.master
--- compat/netbsd32/syscalls.master	12 Jul 2005 07:45:34 -0000	1.35
+++ compat/netbsd32/syscalls.master	15 Jul 2005 12:47:41 -0000
@@ -542,8 +542,11 @@
 342	UNIMPL
 343	STD		{ int netbsd32_rasctl(netbsd32_caddr_t addr, netbsd32_size_t len,=
 \
 			    int op); }
-344	UNIMPL
-345	UNIMPL
+344	NOARGS		{ int sys_kqueue(void); }
+345	STD		{ int netbsd32_kevent(int fd, \
+			    netbsd32_keventp_t changelist, netbsd32_size_t nchanges, \
+			    netbsd32_keventp_t eventlist, netbsd32_size_t nevents, \
+			    netbsd32_timespecp_t timeout); }
 346	UNIMPL
 347	UNIMPL
 348	UNIMPL
--- /dev/null	Fri Jul 15 03:28:00 2005
+++ compat/netbsd32/netbsd32_event.c	Thu Jul 14 23:25:07 2005
@@ -0,0 +1,100 @@
+/*	$NetBSD$	*/
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/select.h>
+#include <sys/event.h>
+#include <sys/eventvar.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+
+#include <compat/netbsd32/netbsd32.h>
+#include <compat/netbsd32/netbsd32_syscall.h>
+#include <compat/netbsd32/netbsd32_syscallargs.h>
+#include <compat/netbsd32/netbsd32_conv.h>
+
+static int
+netbsd32_kevent_fetch_timeout(const void *src, void *dest, size_t length)
+{
+	struct netbsd32_timespec ts32;
+	int error;
+
+	KASSERT(length =3D=3D sizeof(struct timespec));
+
+	error =3D copyin(src, &ts32, sizeof(ts32));
+	if (error)
+		return error;
+	netbsd32_to_timespec(&ts32, (struct timespec *)dest);
+	return 0;
+}
+
+static int
+netbsd32_kevent_fetch_changes(void *private, const struct kevent *changeli=
st,
+    struct kevent *changes, size_t index, int n)
+{
+	const struct netbsd32_kevent *src =3D
+	    (const struct netbsd32_kevent *)changelist;
+	struct netbsd32_kevent *kev32, *changes32 =3D private;
+	int error, i;
+
+	error =3D copyin(src + index, changes32, n * sizeof(*changes32));
+	if (error)
+		return error;
+	for (i =3D 0, kev32 =3D changes32; i < n; i++, kev32++, changes++)
+		netbsd32_to_kevent(kev32, changes);
+	return 0;
+}
+
+static int
+netbsd32_kevent_put_events(void *private, struct kevent *events,
+    struct kevent *eventlist, size_t index, int n)
+{
+	struct netbsd32_kevent *kev32, *events32 =3D private;
+	int i;
+
+	for (i =3D 0, kev32 =3D events32; i < n; i++, kev32++, events++)
+		netbsd32_from_kevent(events, kev32);
+	kev32 =3D (struct netbsd32_kevent *)eventlist;
+	return  copyout(events32, kev32, n * sizeof(*events32));
+}
+
+int
+netbsd32_kevent(struct lwp *l, void *v, register_t *retval)
+{
+	struct netbsd32_kevent_args /* {
+		syscallarg(int) fd;
+		syscallarg(netbsd32_keventp_t) changelist;
+		syscallarg(netbsd32_size_t) nchanges;
+		syscallarg(netbsd32_keventp_t) eventlist;
+		syscallarg(netbsd32_size_t) nevents;
+		syscallarg(netbsd32_timespecp_t) timeout;
+	} */ *uap =3D v;
+	int error;
+	size_t maxalloc, nchanges, nevents;
+	struct kevent_ops netbsd32_kevent_ops =3D {
+		keo_fetch_timeout: netbsd32_kevent_fetch_timeout,
+		keo_fetch_changes: netbsd32_kevent_fetch_changes,
+		keo_put_events: netbsd32_kevent_put_events,
+	};
+
+	nchanges =3D SCARG(uap, nchanges);
+	nevents =3D SCARG(uap, nevents);
+	maxalloc =3D MIN(KQ_NEVENTS, MAX(nchanges, nevents));
+	netbsd32_kevent_ops.keo_private =3D
+	    malloc(maxalloc * sizeof(struct netbsd32_kevent), M_TEMP,
+	    M_WAITOK);
+
+	error =3D kevent1(l, retval, SCARG(uap, fd),
+	    NETBSD32PTR64(SCARG(uap, changelist)), nchanges,
+	    NETBSD32PTR64(SCARG(uap, eventlist)), nevents,
+	    NETBSD32PTR64(SCARG(uap, timeout)), &netbsd32_kevent_ops);
+
+	free(netbsd32_kevent_ops.keo_private, M_TEMP);
+	return error;
+}

--AHVSF3we4xtO5oi5--

--sr8SBrQ3fbgntwtR
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (NetBSD)

iQEVAwUBQtex5NgoQloHrPnoAQKiKQf/XNWvKIubCg2uGTxEZXmJVpKI1RN4uq27
iIcNZrV7NqcuoLyazt/NjCWpjKMaug0kmSANsRTwchpKZ3yaS+a6vYcoh1fTU+ll
Mouf+DL0BYMDWvYQoegvAYEfv68I0uNniiKm49WR1n3Ajt/Vnxj3yl9hGWOF5PHU
/Lf8AnNP860AV68jTuPxH6A439MauOBUAZEJkmXpbznUOD1w267Hmfj/NfbAqoUe
dbRXbZ9SihLHyxKF5G5PXl45UFqlakGPczvtzqZ336/XzrKPFEHXwIFOy/U/fpbk
7yPYlkuX9SrCrB/IgKkpUtWWGCmgt26EfNwlIS8HvIVacgtpjKITAw==
=9c2u
-----END PGP SIGNATURE-----

--sr8SBrQ3fbgntwtR--