diff --git a/src/backend.cmod b/src/backend.cmod
index d448c2e22365a35df77ddae249809fc3f54af96c..b7900497eff71671143c361f90d550e0815506af 100644
--- a/src/backend.cmod
+++ b/src/backend.cmod
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: backend.cmod,v 1.101 2004/04/02 19:37:26 grubba Exp $
+|| $Id: backend.cmod,v 1.102 2004/04/03 12:51:36 grubba Exp $
 */
 
 #include "global.h"
-RCSID("$Id: backend.cmod,v 1.101 2004/04/02 19:37:26 grubba Exp $");
+RCSID("$Id: backend.cmod,v 1.102 2004/04/03 12:51:36 grubba Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include <errno.h>
@@ -212,13 +212,14 @@ struct Backend_struct *really_get_backend_for_fd(int fd)
  */
 
 #ifndef HAVE_AND_USE_POLL
+/* Various BSDs have simulated poll(2) APIs. */
 #undef HAVE_POLL
 #endif
 
 #ifdef HAVE_POLL
 
 /*
- * Backend using poll(2)
+ * Backends using poll(2) or similar.
  */
 
 #ifdef HAVE_POLL_H
@@ -229,13 +230,65 @@ struct Backend_struct *really_get_backend_for_fd(int fd)
 #include <sys/poll.h>
 #endif /* HAVE_SYS_POLL_H */
 
+/* Some constants... */
+
+/* Notes on POLLRDNORM and POLLIN:
+ *
+ * According to the AIX manual, POLLIN and POLLRDNORM are both set
+ * if there's a nonpriority message on the read queue. POLLIN is
+ * also set if the message is of 0 length.
+ */
+
+#ifndef POLLRDNORM
+#define POLLRDNORM	POLLIN
+#endif /* !POLLRDNORM */
+
+#ifndef POLLRDBAND
+#define POLLRDBAND	POLLPRI
+#endif /* !POLLRDBAND */
+
+#ifndef POLLWRNORM
+#define POLLWRNORM	POLLOUT
+#endif /* POLLWRNORM */
+
+#ifndef POLLWRBAND
+#define POLLWRBAND	POLLOUT
+#endif /* !POLLWRBAND */
+
+#define MY_POLLIN POLLRDNORM|POLLIN
+#define MY_POLLOUT POLLWRNORM|POLLOUT
+
+#define MY_POLLEXCEPT POLLRDBAND|POLLRDNORM|POLLIN
+#define MY_POLLRDBAND POLLRDBAND
+#define MY_POLLWREXCEPT POLLWRBAND|POLLWRNORM|POLLOUT
+#define MY_POLLWRBAND POLLWRBAND
+
+#if (POLLRDBAND != POLLRDNORM) && (POLLRDBAND != POLLIN)
+#define RDBAND_IS_SPECIAL
+#endif
+
+#if (POLLWRBAND != POLLOUT) && (POLLWRBAND != POLLWRNORM)
+#define WRBAND_IS_SPECIAL
+#endif
+
 #if defined(HAVE_SYS_DEVPOLL_H) && defined(PIKE_POLL_DEVICE)
+/*
+ * Backend using /dev/poll-style poll device.
+ *
+ * Used on:
+ *   Solaris 7 + patches and above.
+ *   OSF/1 + patches and above.
+ *   IRIX 5.6.15m and above.
+ * Broken on:
+ *   Solaris 7/x86 + patches (process hangs in device wait).
+ */
 #include <sys/devpoll.h>
 
 #define USE_POLL_DEVICE
 #define USE_DEVPOLL
 #define POLL_EVENT	struct pollfd
 #define OPEN_POLL_DEVICE()	open(PIKE_POLL_DEVICE, O_RDWR)
+#define CHILD_NEEDS_TO_REOPEN
 
 int POLL_DEVICE_SET_EVENTS(int pfd, int fd, INT32 events)
 {
@@ -274,6 +327,15 @@ int POLL_DEVICE_SET_EVENTS(int pfd, int fd, INT32 events)
 }
 	
 #elif defined(HAVE_SYS_EPOLL_H) && defined(WITH_EPOLL)
+/*
+ * Backend using /dev/epoll-style poll device.
+ *
+ * Used on:
+ *   Linux 2.6 and above.
+ * Note:
+ *   Some libc's are missing wrappers for the system calls, so
+ *   we include the appropriate wrappers below.
+ */
 #include <sys/epoll.h>
 
 /* The following three are defined by <gnu/stubs.h> which is included
@@ -372,75 +434,15 @@ int POLL_DEVICE_SET_EVENTS(int pfd, int fd, INT32 events)
     
   return e;
 }
-	
-#endif /* HAVE_SYS_DEVPOLL_H || HAVE_SYS_EPOLL_H */
 
-#ifdef USE_POLL_DEVICE
-#ifndef OPEN_POLL_DEVICE
-#define OPEN_POLL_DEVICE()	(errno = ENODEV, -1)	/* Error */
-#endif /* !OPEN_POLL_DEVICE */
-#ifndef POLL_SET_SIZE
-#define POLL_SET_SIZE		32
-#endif /* !POLL_SET_SIZE */
-#endif /* USE_POLL_DEVICE */
-
-#ifndef GET_FD
-#define GET_FD(EVENT)		EVENT.fd
-#endif
-#ifndef GET_EVENTS
-#define GET_EVENTS(EVENT)	EVENT.revents
-#endif
-/* Some constants... */
+#else /* !USE_POLL_DEVICE */
 
-/* Notes on POLLRDNORM and POLLIN:
+/*
+ * Backend using poll(2).
  *
- * According to the AIX manual, POLLIN and POLLRDNORM are both set
- * if there's a nonpriority message on the read queue. POLLIN is
- * also set if the message is of 0 length.
- */
-
-#ifndef POLLRDNORM
-#define POLLRDNORM	POLLIN
-#endif /* !POLLRDNORM */
-
-#ifndef POLLRDBAND
-#define POLLRDBAND	POLLPRI
-#endif /* !POLLRDBAND */
-
-#ifndef POLLWRNORM
-#define POLLWRNORM	POLLOUT
-#endif /* POLLWRNORM */
-
-#ifndef POLLWRBAND
-#define POLLWRBAND	POLLOUT
-#endif /* !POLLWRBAND */
-
-#define MY_POLLIN POLLRDNORM|POLLIN
-#define MY_POLLOUT POLLWRNORM|POLLOUT
-
-#define MY_POLLEXCEPT POLLRDBAND|POLLRDNORM|POLLIN
-#define MY_POLLRDBAND POLLRDBAND
-#define MY_POLLWREXCEPT POLLWRBAND|POLLWRNORM|POLLOUT
-#define MY_POLLWRBAND POLLWRBAND
-
-#if (POLLRDBAND != POLLRDNORM) && (POLLRDBAND != POLLIN)
-#define RDBAND_IS_SPECIAL
-#endif
-
-#if (POLLWRBAND != POLLOUT) && (POLLWRBAND != POLLWRNORM)
-#define WRBAND_IS_SPECIAL
-#endif
-
-#ifdef USE_POLL_DEVICE
-
-/* NOTE: With poll devices the poll set is recalculated each time it's
- *       potentially changed, so MY_FD_{SET,CLR}() are not used.
+ * This is used on most older SVR4- or POSIX-style systems.
  */
 
-#define copy_selectors(TO, FROM)
-
-#else /* !USE_POLL_DEVICE */
-
 struct selectors
 {
   struct pollfd *poll_fds;
@@ -546,12 +548,77 @@ static void copy_selectors(struct active_selectors *to,
   to->num_in_poll=from->num_in_poll;
 }
 
+#endif /* HAVE_SYS_DEVPOLL_H || HAVE_SYS_EPOLL_H */
+
+#ifdef USE_POLL_DEVICE
+#ifndef POLL_SET_SIZE
+#define POLL_SET_SIZE		32
+#endif /* !POLL_SET_SIZE */
 #endif /* USE_POLL_DEVICE */
 
-#else  /* !HAVE_POLL */
+#ifndef GET_FD
+#define GET_FD(EVENT)		EVENT.fd
+#endif
+#ifndef GET_EVENTS
+#define GET_EVENTS(EVENT)	EVENT.revents
+#endif
+
+#ifdef USE_POLL_DEVICE
+
+/* NOTE: With poll devices the poll set is recalculated each time it's
+ *       potentially changed, so MY_FD_{SET,CLR}() are not used.
+ */
+
+#define copy_selectors(TO, FROM)
+
+#endif /* USE_POLL_DEVICE */
+
+#elif defined(HAVE_SYS_EVENT_H) && defined(HAVE_KQUEUE) /* && !HAVE_POLL */
+/*
+ * Backend using kqueue-style poll device.
+ *
+ * FIXME: Not fully implemented yet!
+ *
+ * Used on
+ *   FreeBSD 4.1 and above.
+ *   MacOS X/Darwin 7.x and above.
+ *   Various other BSDs.
+ */
+
+#include <sys/event.h>
+
+#define USE_KQUEUE
+#define POLL_EVENT	struct kevent
+#define OPEN_POLL_DEVICE()	kqueue()
+#define CHILD_NEEDS_TO_REOPEN
+
+#define MY_POLLIN	EVFILT_READ
+#define MY_POLLOUT	EVFILT_WRITE
+
+/* FIXME: The kqueue API has no documented support for out of band data. */
+#define MY_POLLEXCEPT	EVFILT_READ
+#define MY_POLLRDBAND	EVFILT_READ
+#define MY_POLLWREXCEPT	EVFILT_WRITE
+#define MY_POLLWRBAND	EVFILT_WRITE
+
+#define MY_SELECT(fds, R, W, E, T)	kqueue(pfd, NULL, 0, evs, nevs, (T))
+
+int MY_FD_CLR(int pfd, int fd, int filter)
+{
+  struct kevent ev;
+  int e;
+
+  EV_SET(&ev, fd, filter, EV_DISABLE, 0, 0, 0);
+  
+  return kqueue(pfd, &ev, 1, NULL, 0, NULL);
+}
+
+#else  /* !HAVE_POLL && !HAVE_KQUEUE */
 
 /*
  * Backend using select(2)
+ *
+ * This is used on most older BSD-style systems, and WIN32.
  */
 
 struct selectors
@@ -614,7 +681,7 @@ static void copy_selectors(struct active_selectors *to,
   to->max_fd=from->max_fd;
 }
 
-#endif	/* HAVE_POLL */
+#endif	/* HAVE_POLL || USE_KQUEUE */
 
 #ifdef USE_POLL_DEVICE
 #  define DO_IF_USE_POLL_DEVICE_ELSE(POLLDEV_CODE, NO_POLLDEV_CODE) POLLDEV_CODE
@@ -2538,14 +2605,6 @@ PIKECLASS Backend
       me->fds=0;
       me->fds_size=0;
 
-#ifndef HAVE_POLL
-      me->set.max_fd=0;
-      my_FD_ZERO(&me->set.read);
-      my_FD_ZERO(&me->set.write);
-      my_FD_ZERO(&me->set.except);
-      /* FIXME: Should there be something else here? */
-      /* me->set.num_fds=0; */
-#else /* HAVE_POLL */
 #ifdef USE_POLL_DEVICE
       if ((me->set = OPEN_POLL_DEVICE()) < 0) {
 	Pike_error("Failed to open poll device (errno:%d)\n", errno);
@@ -2553,7 +2612,7 @@ PIKECLASS Backend
       set_close_on_exec(me->set, 1);
 
       register_backend(me);
-#else /* !USE_POLL_DEVICE */
+#elif defined(HAVE_POLL)
       me->set.poll_fds=0;
       me->set.poll_fd_size=0;
       me->set.num_in_poll=0;
@@ -2561,8 +2620,14 @@ PIKECLASS Backend
       me->active_set.poll_fds=0;
       me->active_set.poll_fd_size=0;
       me->active_set.num_in_poll=0;
-#endif /* USE_POLL_DEVICE */
-#endif /* !HAVE_POLL */
+#else /* !HAVE_POLL */
+      me->set.max_fd=0;
+      my_FD_ZERO(&me->set.read);
+      my_FD_ZERO(&me->set.write);
+      my_FD_ZERO(&me->set.except);
+      /* FIXME: Should there be something else here? */
+      /* me->set.num_fds=0; */
+#endif /* USE_POLL_DEVICE || HAVE_POLL */
 
       if(pike_make_pipe(me->wakeup_pipe) < 0)
 	Pike_error("Couldn't create backend wakeup pipe! errno=%d.\n",errno);
@@ -2856,10 +2921,8 @@ void init_backend(void)
     add_object_constant("__backend",o,0);
     free_object(o);
   }
-#ifdef USE_DEVPOLL
-  /* /dev/poll fds get invalidated at fork
-   * on Solaris and IRIX.
-   */
+#ifdef CHILD_NEEDS_TO_REOPEN
+  /* /dev/poll and kqueue fds get invalidated at fork. */
   dmalloc_accept_leak(add_to_callback(&fork_child_callback,
 				      reopen_all_backends, NULL, NULL));
 #endif