Subject: kevent(2) under COMPAT_NETBSD32
To: None <tech-kern@netbsd.org>
From: Quentin Garnier <cube@cubidou.net>
List: tech-kern
Date: 07/13/2005 15:42:05
--R4+lwT0Y15rLnKR0
Content-Type: multipart/mixed; boundary="WOTjKnJ88wpJKlWH"
Content-Disposition: inline


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

Hi folks,

I won't lie:  kevent(2) is about as netbsd32-unfriendly as a syscall
can be.

The patch I've attached does the following things:
 o add a copyinout_t type that matched the copyin/copyout prototype,
   which will be useful when passing a copyin-function
 o split kevent1() from sys_kevent().  kevent1() takes three
   functional arguments to
    - retrieve the timespec struct
    - fetch one or several kevent structures from user space
    - store one or several kevent structures to user space
 o make kqueue_scan() accept a functional argument to store the
   kevent structures into user space
 o implement the netbsd32 version

As you can see, while not disrupting the current structure of kevent(),
it allows a very straightforward netbsd32 version.

However, it still introduces a bit of complexity in kevent() (although
the native path only gets one more function call and a few indirections),
and more importantly it probably makes code sharing with FreeBSD a bit
harder, although I don't know how close to the FreeBSD implementations
our port has stayed.

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.

Comments?

--=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.

--WOTjKnJ88wpJKlWH
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	13 Jul 2005 13:28:44 -0000
@@ -54,11 +54,10 @@
 #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 *, kevent_put_event=
_t);
 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 +628,20 @@
 /*
  * kevent(2) system call.
  */
+static int
+kevent_fetch_changes(const struct kevent *changelist, struct kevent *chang=
es,
+    size_t index, int n)
+{
+	return copyin(changelist + index, changes, n * sizeof(*changes));
+}
+
+static int
+kevent_put_event(struct kevent *events, struct kevent *eventlist, size_t i=
ndex,
+    int n)
+{
+	return copyout(events, eventlist + index, n * sizeof(*events));
+}
+
 int
 sys_kevent(struct lwp *l, void *v, register_t *retval)
 {
@@ -640,17 +653,30 @@
 		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), copyin, kevent_fetch_changes,
+	    kevent_put_event);
+}
+
+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, copyinout_t fetch_time=
out,
+    kevent_fetch_changes_t fetch_changes, kevent_put_event_t put_event)
+{
 	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 +687,22 @@
=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 (*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 (*fetch_changes)(changelist, kq->kq_kev, ichange, n);
 		if (error)
 			goto done;
 		for (i =3D 0; i < n; i++) {
@@ -685,24 +711,22 @@
 			/* 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 (*put_event)(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 +735,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, put_eve=
nt);
  done:
 	FILE_UNUSE(fp, p);
 	return (error);
@@ -866,18 +889,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,
+    kevent_put_event_t put_event)
 {
 	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 +1020,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 put_event(&kq->kq_kev[0], ulistp, nevents,
+			    nkev);
+			nevents +=3D nkev;
 			nkev =3D 0;
 			kevp =3D kq->kq_kev;
 			s =3D splsched();
@@ -1016,11 +1040,9 @@
 	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 put_event(&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	13 Jul 2005 13:28:44 -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	13 Jul 2005 13:28:44 -0000
@@ -198,13 +198,25 @@
 #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)(const struct kevent *, struct kevent=
 *,
+    size_t, int);
+typedef	int (*kevent_put_event_t)(struct kevent *, struct kevent *, size_t,
+    int);
+
+int	kevent1(struct lwp *, register_t *, int, const struct kevent *,
+    size_t, struct kevent *, size_t, const struct timespec *, copyinout_t,
+    kevent_fetch_changes_t, kevent_put_event_t);
+
 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	13 Jul 2005 13:28:44 -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	13 Jul 2005 13:28:44 -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	13 Jul 2005 13:28:45 -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	13 Jul 2005 13:28:45 -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	13 Jul 2005 13:28:46 -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	13 Jul 2005 13:28:46 -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	13 Jul 2005 13:28:47 -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	13 Jul 2005 13:28:48 -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	Wed Jul 13 03:27:58 2005
+++ compat/netbsd32/netbsd32_event.c	Wed Jul 13 15:25:11 2005
@@ -0,0 +1,91 @@
+/*	$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(const struct kevent *changelist,
+    struct kevent *changes, size_t index, int n)
+{
+	const struct netbsd32_kevent *src =3D
+	    (const struct netbsd32_kevent *)changelist;
+	struct netbsd32_kevent *kev32, *changes32;
+	int error, i;
+
+	changes32 =3D malloc(n * sizeof(*changes32), M_TEMP, M_WAITOK);
+	error =3D copyin(src + index, changes32, n * sizeof(*changes32));
+	if (error)
+		goto out;
+	for (i =3D 0, kev32 =3D changes32; i < n; i++, kev32++, changes++)
+		netbsd32_to_kevent(kev32, changes);
+
+out:
+	free(changes32, M_TEMP);
+	return error;
+}
+
+static int
+netbsd32_kevent_put_event(struct kevent *events, struct kevent *eventlist,
+    size_t index, int n)
+{
+	struct netbsd32_kevent *kev32, *events32;
+	int error, i;
+
+	events32 =3D malloc(n * sizeof(*events32), M_TEMP, M_WAITOK);
+	for (i =3D 0, kev32 =3D events32; i < n; i++, kev32++, events++)
+		netbsd32_from_kevent(events, kev32);
+	kev32 =3D (struct netbsd32_kevent *)eventlist;
+	error =3D copyout(events32, kev32, n * sizeof(*events32));
+	free(events32, M_TEMP);
+	return error;
+}
+
+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;
+
+	return kevent1(l, retval, SCARG(uap, fd),
+	    NETBSD32PTR64(SCARG(uap, changelist)), SCARG(uap, nchanges),
+	    NETBSD32PTR64(SCARG(uap, eventlist)), SCARG(uap, nevents),
+	    NETBSD32PTR64(SCARG(uap, timeout)), netbsd32_kevent_fetch_timeout,
+	    netbsd32_kevent_fetch_changes, netbsd32_kevent_put_event);
+}

--WOTjKnJ88wpJKlWH--

--R4+lwT0Y15rLnKR0
Content-Type: application/pgp-signature
Content-Disposition: inline

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

iQEVAwUBQtUaLdgoQloHrPnoAQJOLgf/Zcr+keReDe2sCStuSAOolpUSuef7lYi1
q83IV3KZS5LRmcH3NMqRq/nQwzQnYJMtsYOXj0J2dm07CjtU3+mBpteBUlD3TVc9
0htJ0YR07XFD68cedF+fmp+I+MLeDF3vZb21oMyh789t6oBo7Yrh1fKY4EHNujsU
KCmffOCnjpJBfg/QOa/EuHTZUfsC+btGQ4cc+WbKmrF41WnvWulq2AzweMSlispx
NcZvmekZNHDYjTR1hf+j3UUVCbBO2tiwSeJY9dhwacH4CNPUvCem9mO08zvmsrPc
vQ3mbpWgD4ppr4DeI8bJqNxJ+8VisnjYVdEmO1ywAXQQjBLOKqJ/vg==
=LfDS
-----END PGP SIGNATURE-----

--R4+lwT0Y15rLnKR0--