Blame SOURCES/xinetd-2.3.14-poll.patch

01101d
diff -Nurp xinetd-2.3.14-orig/config.h.in xinetd-2.3.14-poll/config.h.in
01101d
--- xinetd-2.3.14-orig/config.h.in	2009-07-27 13:27:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/config.h.in	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -106,6 +106,8 @@
01101d
 
01101d
 #undef HAVE_HOWL
01101d
 
01101d
+#undef HAVE_POLL
01101d
+
01101d
 /* OS specific */
01101d
 #undef solaris
01101d
 
01101d
diff -Nurp xinetd-2.3.14-orig/configure.in xinetd-2.3.14-poll/configure.in
01101d
--- xinetd-2.3.14-orig/configure.in	2009-09-02 11:32:54.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/configure.in	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -35,6 +35,7 @@ AC_CHECK_LIB(c, sys_siglist, [AC_DEFINE(
01101d
 AC_CHECK_FUNC(gai_strerror,[AC_DEFINE(HAVE_GAI_STRERROR, 1, "")])
01101d
 AC_CHECK_FUNC(freeaddrinfo,[AC_DEFINE(HAVE_FREEADDRINFO, 1, "")])
01101d
 AC_CHECK_FUNC(getaddrinfo,[AC_DEFINE(HAVE_GETADDRINFO, 1, "")])
01101d
+AC_CHECK_FUNC(poll, [AC_DEFINE(HAVE_POLL, 1, "")])
01101d
 
01101d
 AC_CHECK_HEADERS(sys/types.h sys/termios.h termios.h sys/ioctl.h sys/select.h rpc/rpc.h rpc/rpcent.h sys/file.h ftw.h machine/reg.h netdb.h)
01101d
 AC_CHECK_HEADER(sys/resource.h, [AC_DEFINE(HAVE_SYS_RESOURCE_H, 1, "")])
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/conf.c xinetd-2.3.14-poll/xinetd/conf.c
01101d
--- xinetd-2.3.14-orig/xinetd/conf.c	2003-12-30 14:44:09.000000000 +0100
01101d
+++ xinetd-2.3.14-poll/xinetd/conf.c	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -209,8 +209,13 @@ unsigned cnf_start_services( struct conf
01101d
    pset_clear( sconfs ) ;
01101d
 
01101d
    if ( debug.on )
01101d
+#ifdef HAVE_POLL
01101d
+      msg( LOG_DEBUG, func, "pfds_last = %d, services_started = %d",
01101d
+            ps.rws.pfds_last, services_started ) ;
01101d
+#else
01101d
       msg( LOG_DEBUG, func, "mask_max = %d, services_started = %d",
01101d
             ps.rws.mask_max, services_started ) ;
01101d
+#endif
01101d
          
01101d
    return( services_started ) ;
01101d
 }
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/defs.h xinetd-2.3.14-poll/xinetd/defs.h
01101d
--- xinetd-2.3.14-orig/xinetd/defs.h	2005-03-29 17:50:34.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/defs.h	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -111,6 +111,15 @@ union xsockaddr {
01101d
 #define LISTEN_BACKLOG               64
01101d
 
01101d
 /*
01101d
+ * constants for limiting ps.rws.fd_list 
01101d
+ */
01101d
+
01101d
+#ifdef HAVE_POLL
01101d
+#define INIT_POLLFDS                 1024
01101d
+#define MAX_POLLFDS                  8192
01101d
+#endif
01101d
+
01101d
+/*
01101d
  * When explicit values are given for enum's, that is because the structures 
01101d
  * that the enum's are in may be initialized by a memory clear operation.
01101d
  */
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/child.c xinetd-2.3.14-poll/xinetd/child.c
01101d
--- xinetd-2.3.14-orig/xinetd/child.c	2003-09-06 16:41:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/child.c	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -109,8 +109,7 @@ void exec_server( const struct server *s
01101d
 
01101d
 
01101d
 #ifdef RLIMIT_NOFILE
01101d
-   rl.rlim_max = ps.ros.orig_max_descriptors ;
01101d
-   rl.rlim_cur = ps.ros.max_descriptors ;
01101d
+   rl.rlim_max = rl.rlim_cur = ps.ros.max_descriptors ;
01101d
    (void) setrlimit( RLIMIT_NOFILE, &rl ) ;
01101d
 #endif
01101d
 #ifdef RLIMIT_AS
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/init.c xinetd-2.3.14-poll/xinetd/init.c
01101d
--- xinetd-2.3.14-orig/xinetd/init.c	2003-09-06 16:41:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/init.c	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -17,7 +17,7 @@
01101d
 #include <unistd.h>
01101d
 #include <stdio.h>
01101d
 #include <errno.h>
01101d
-
01101d
+#include <malloc.h>
01101d
 #include "sio.h"
01101d
 #include "init.h"
01101d
 #include "defs.h"
01101d
@@ -140,7 +140,6 @@ static void set_fd_limit(void)
01101d
 {
01101d
 #ifdef RLIMIT_NOFILE
01101d
    struct rlimit rl ;
01101d
-   rlim_t maxfd ;
01101d
     
01101d
    /*
01101d
     * Set the soft file descriptor limit to the hard limit.
01101d
@@ -151,25 +150,9 @@ static void set_fd_limit(void)
01101d
       exit( 1 ) ;
01101d
    }
01101d
 
01101d
-   maxfd = rl.rlim_max;
01101d
    if ( rl.rlim_max == RLIM_INFINITY ) 
01101d
       rl.rlim_max = FD_SETSIZE;
01101d
 
01101d
-   /* XXX: a dumb way to prevent fd_set overflow possibilities; the rest
01101d
-    * of xinetd should be changed to use an OpenBSD inetd-like fd_grow(). */
01101d
-   if ( rl.rlim_max > FD_SETSIZE )
01101d
-      rl.rlim_max = FD_SETSIZE;
01101d
-     
01101d
-   rl.rlim_cur = rl.rlim_max ;
01101d
-   if ( setrlimit( RLIMIT_NOFILE, &rl ) == -1 )
01101d
-   {
01101d
-      syscall_failed("setrlimit(RLIMIT_NOFILE)");
01101d
-      ps.ros.max_descriptors = FD_SETSIZE;
01101d
-      ps.ros.orig_max_descriptors = FD_SETSIZE;
01101d
-      return ;
01101d
-   }
01101d
-
01101d
-   ps.ros.orig_max_descriptors = maxfd ;
01101d
    ps.ros.max_descriptors = rl.rlim_max ;
01101d
 #else      /* ! RLIMIT_NOFILE */
01101d
    ps.ros.max_descriptors = getdtablesize() ;
01101d
@@ -292,15 +275,27 @@ static pset_h new_table( unsigned size )
01101d
  */
01101d
 static void init_rw_state( void )
01101d
 {
01101d
+   const char *func = "init_rw_state" ;
01101d
    SERVERS( ps ) = new_table( 0 ) ;
01101d
    RETRIES( ps ) = new_table( 0 ) ;
01101d
    SERVICES( ps ) = new_table( 0 ) ;
01101d
 
01101d
    ps.rws.descriptors_free = ps.ros.max_descriptors - DESCRIPTORS_RESERVED ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   ps.rws.pfds_allocated = INIT_POLLFDS ;
01101d
+   ps.rws.pfd_array = (struct pollfd *) 
01101d
+                      malloc( sizeof( struct pollfd ) * ps.rws.pfds_allocated ) ;
01101d
+   if ( ps.rws.pfd_array == NULL ) 
01101d
+   {
01101d
+      out_of_memory(func);
01101d
+      exit( 1 ) ;
01101d
+   }
01101d
+   ps.rws.pfds_last = 0 ;
01101d
+#else
01101d
    FD_ZERO( &ps.rws.socket_mask ) ;
01101d
    ps.rws.mask_max = 0 ;
01101d
-
01101d
+#endif /* HAVE_POLL */
01101d
 }
01101d
 
01101d
 
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/intcommon.c xinetd-2.3.14-poll/xinetd/intcommon.c
01101d
--- xinetd-2.3.14-orig/xinetd/intcommon.c	2003-08-06 08:12:10.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/intcommon.c	2009-09-03 16:15:49.000000000 +0200
01101d
@@ -14,6 +14,9 @@
01101d
 #include <errno.h>
01101d
 #include <stdlib.h>
01101d
 #include <unistd.h>
01101d
+#ifdef HAVE_POLL
01101d
+#include <poll.h>
01101d
+#endif
01101d
 
01101d
 #include "intcommon.h"
01101d
 #include "msg.h"
01101d
@@ -36,27 +39,38 @@ void int_fail( const struct intercept_s 
01101d
 /*
01101d
  * Returns either a positive number or -1
01101d
  */
01101d
+#ifdef HAVE_POLL
01101d
+int int_poll( int pfds_last, struct pollfd *pfd_array )
01101d
+{
01101d
+   const char *func = "int_poll" ;
01101d
+#else
01101d
 int int_select( int max, fd_set *read_mask )
01101d
 {
01101d
    const char *func = "int_select" ;
01101d
+#endif
01101d
 
01101d
    for ( ;; )
01101d
    {
01101d
       int n_ready ;
01101d
 
01101d
-      n_ready = select( max+1, read_mask,
01101d
-                                 FD_SET_NULL, FD_SET_NULL, TIMEVAL_NULL ) ;
01101d
+      do {
01101d
+#ifdef HAVE_POLL
01101d
+         n_ready = poll( pfd_array, pfds_last, -1 );
01101d
+#else
01101d
+         n_ready = select( max+1, read_mask,
01101d
+                           FD_SET_NULL, FD_SET_NULL, TIMEVAL_NULL ) ;
01101d
+#endif
01101d
+      } while (n_ready == -1 && errno == EINTR);
01101d
+
01101d
+
01101d
       if ( n_ready > 0 )
01101d
          return( n_ready ) ;
01101d
-      else if ( n_ready == -1 ) {
01101d
-         if ( errno == EINTR )
01101d
-            continue ;
01101d
-         else
01101d
-         {
01101d
-            msg( LOG_ERR, func, "select: %m" ) ;
01101d
-            return( -1 ) ;
01101d
-         }
01101d
-      }
01101d
+#ifdef HAVE_POLL
01101d
+      msg( LOG_ERR, func, "poll: %m" ) ;
01101d
+#else
01101d
+      msg( LOG_ERR, func, "select: %m" ) ;
01101d
+#endif
01101d
+      return( -1 ) ;
01101d
    }
01101d
 }
01101d
 
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/internals.c xinetd-2.3.14-poll/xinetd/internals.c
01101d
--- xinetd-2.3.14-orig/xinetd/internals.c	2003-09-06 16:41:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/internals.c	2009-09-03 10:38:29.000000000 +0200
01101d
@@ -53,6 +53,9 @@ void dump_internal_state(void)
01101d
    const char *dump_file = DUMP_FILE ;
01101d
    time_t current_time ;
01101d
    int fd ;
01101d
+#ifdef HAVE_POLL
01101d
+   int *listed_fds;
01101d
+#endif
01101d
    unsigned u ;
01101d
    const char *func = "dump_internal_state" ;
01101d
 
01101d
@@ -104,6 +107,41 @@ void dump_internal_state(void)
01101d
       server_dump( SERP( pset_pointer( RETRIES( ps ), u ) ), dump_fd ) ;
01101d
    Sputchar( dump_fd, '\n' ) ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   /*
01101d
+    * Dump the socket mask
01101d
+    */
01101d
+   listed_fds = (int *)calloc(sizeof(int),ps.ros.max_descriptors);
01101d
+   if (listed_fds != NULL)
01101d
+   {
01101d
+      Sprint( dump_fd, "Socket mask:" ) ;
01101d
+      for ( fd = 0 ; fd < ps.rws.pfds_last ; fd++ )
01101d
+      {
01101d
+         listed_fds[ps.rws.pfd_array[fd].fd] = 1;
01101d
+         Sprint( dump_fd, " %d", ps.rws.pfd_array[fd].fd ) ;
01101d
+      }
01101d
+      Sputchar( dump_fd, '\n' ) ;
01101d
+      Sprint( dump_fd, "pfds_last = %d\n", ps.rws.pfds_last ) ;
01101d
+
01101d
+      /*
01101d
+       * Dump the descriptors that are open and are *not* in the socket list
01101d
+       */
01101d
+      Sprint( dump_fd, "Open descriptors (not in socket mask):" ) ;
01101d
+      for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ )
01101d
+      {
01101d
+         struct stat st ;
01101d
+
01101d
+         if ( !listed_fds[fd] && fstat( fd, &st ) != -1 )
01101d
+            Sprint( dump_fd, " %d", fd ) ;
01101d
+      }
01101d
+
01101d
+      Sputchar( dump_fd, '\n' ) ;
01101d
+      Sputchar( dump_fd, '\n' ) ;
01101d
+      free(listed_fds);
01101d
+   }
01101d
+   else
01101d
+     Sprint( dump_fd, "Could not dump open descriptors, not enough memory!\n" );
01101d
+#else /* !HAVE_POLL */
01101d
    /*
01101d
     * Dump the socket mask
01101d
     */
01101d
@@ -114,6 +152,7 @@ void dump_internal_state(void)
01101d
    Sputchar( dump_fd, '\n' ) ;
01101d
    Sprint( dump_fd, "mask_max = %d\n", ps.rws.mask_max ) ;
01101d
 
01101d
+
01101d
    /*
01101d
     * Dump the descriptors that are open and are *not* in the socket mask
01101d
     */
01101d
@@ -130,6 +169,7 @@ void dump_internal_state(void)
01101d
    }
01101d
    Sputchar( dump_fd, '\n' ) ;
01101d
    Sputchar( dump_fd, '\n' ) ;
01101d
+#endif /* !HAVE_POLL */
01101d
 
01101d
    Sprint( dump_fd, "active_services = %d\n", ps.rws.active_services ) ;
01101d
    Sprint( dump_fd, "available_services = %d\n", ps.rws.available_services ) ;
01101d
@@ -162,7 +202,6 @@ enum check_type { PERIODIC, USER_REQUEST
01101d
 static void consistency_check( enum check_type type )
01101d
 {
01101d
    int         fd ;
01101d
-   fd_set      socket_mask_copy ;
01101d
    unsigned    u ;
01101d
    int         errors ;
01101d
    unsigned    total_running_servers        = 0 ;
01101d
@@ -171,7 +210,19 @@ static void consistency_check( enum chec
01101d
    bool_int    service_count_check_failed   = FALSE ;
01101d
    const char  *func                        = "consistency_check" ;
01101d
 
01101d
+
01101d
+#ifdef HAVE_POLL
01101d
+  struct pollfd *pfd_array_copy = calloc(sizeof(struct pollfd), ps.rws.pfds_last);
01101d
+  if (pfd_array_copy == NULL)
01101d
+  {
01101d
+     msg( LOG_ERR, func, "Could not run consistency check! Not enough memory!\n" ) ;
01101d
+     return;
01101d
+  }
01101d
+  memcpy(pfd_array_copy, ps.rws.pfd_array, ps.rws.pfds_last*sizeof(struct pollfd));
01101d
+#else /* !HAVE_POLL */
01101d
+   fd_set      socket_mask_copy ;
01101d
    socket_mask_copy = ps.rws.socket_mask ;
01101d
+#endif /* HAVE_POLL */
01101d
 
01101d
    for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
01101d
    {
01101d
@@ -184,9 +235,22 @@ static void consistency_check( enum chec
01101d
 
01101d
       if ( SVC_IS_AVAILABLE( sp ) || SVC_IS_DISABLED ( sp ) )
01101d
       {
01101d
+
01101d
          /*
01101d
           * In this case, there may be some servers running
01101d
           */
01101d
+#ifdef HAVE_POLL
01101d
+         if ( pfd_array_copy[ SVC_POLLFD_OFF( sp ) ].events )
01101d
+         {
01101d
+            if ( SVC_IS_DISABLED( sp ) )
01101d
+            {
01101d
+               msg( LOG_ERR, func,
01101d
+                  "fd of disabled service %s still in socket mask", sid ) ;
01101d
+               error_count++ ;
01101d
+            }
01101d
+            pfd_array_copy[ SVC_POLLFD_OFF( sp ) ].events = 0;
01101d
+         }
01101d
+#else /* !HAVE_POLL */
01101d
          if ( FD_ISSET( SVC_FD( sp ), &socket_mask_copy ) )
01101d
          {
01101d
             if ( SVC_IS_DISABLED( sp ) )
01101d
@@ -197,8 +261,9 @@ static void consistency_check( enum chec
01101d
             }
01101d
             FD_CLR( SVC_FD( sp ), &socket_mask_copy ) ;
01101d
          }
01101d
-         error_count += thread_check( sp, running_servers, retry_servers ) ;
01101d
+#endif /* HAVE_POLL */
01101d
 
01101d
+         error_count += thread_check( sp, running_servers, retry_servers ) ;
01101d
          errors = service_count_check( sp, running_servers, retry_servers ) ;
01101d
          if ( ! errors && ! service_count_check_failed )
01101d
          {
01101d
@@ -248,6 +313,18 @@ static void consistency_check( enum chec
01101d
    /*
01101d
     * Check if there are any descriptors set in socket_mask_copy
01101d
     */
01101d
+#ifdef HAVE_POLL
01101d
+   for ( fd = 0 ; fd < ps.rws.pfds_last ; fd++)
01101d
+     if ( pfd_array_copy[fd].events && pfd_array_copy[fd].fd != signals_pending[0] && 
01101d
+          pfd_array_copy[fd].fd != signals_pending[1] )
01101d
+     {
01101d
+         msg( LOG_ERR, func,
01101d
+            "descriptor %d set in socket mask but there is no service for it",
01101d
+               fd ) ;
01101d
+         error_count++ ;
01101d
+     }
01101d
+   free(pfd_array_copy);
01101d
+#else /* !HAVE_POLL */
01101d
    for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ )
01101d
       if ( FD_ISSET( fd, &socket_mask_copy ) && ((fd != signals_pending[0]) && fd != signals_pending[1]))
01101d
       {
01101d
@@ -256,6 +333,7 @@ static void consistency_check( enum chec
01101d
                fd ) ;
01101d
          error_count++ ;
01101d
       }
01101d
+#endif /* !HAVE_POLL */
01101d
 
01101d
    if ( error_count != 0 )
01101d
       msg( LOG_WARNING, func,
01101d
@@ -304,7 +382,6 @@ static unsigned service_count_check( str
01101d
 }
01101d
 
01101d
 
01101d
-
01101d
 /*
01101d
  * If the service is single-threaded:
01101d
  *         if the descriptor is set in the socket mask, there must
01101d
@@ -317,7 +394,11 @@ static unsigned thread_check( struct ser
01101d
                                unsigned retry_servers )
01101d
 {
01101d
    unsigned error_count = 0 ;
01101d
+#ifdef HAVE_POLL
01101d
+   struct pollfd *pfd= SVC_POLLFD( sp ) ;
01101d
+#else
01101d
    int sd = SVC_FD( sp ) ;
01101d
+#endif
01101d
    char *sid = SVC_ID( sp ) ;
01101d
    const char *func = "thread_check" ;
01101d
 
01101d
@@ -325,13 +406,21 @@ static unsigned thread_check( struct ser
01101d
    {
01101d
       bool_int has_servers = ( running_servers + retry_servers != 0 ) ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+      if ( has_servers && pfd->events )
01101d
+#else
01101d
       if ( has_servers && FD_ISSET( sd, &ps.rws.socket_mask ) )
01101d
+#endif
01101d
       {
01101d
          msg( LOG_ERR, func,
01101d
 "Active single-threaded service %s: server running, descriptor set", sid ) ;
01101d
          error_count++ ;
01101d
       }
01101d
+#ifdef HAVE_POLL
01101d
+      if ( !has_servers && !pfd->events )
01101d
+#else
01101d
       if ( !has_servers && !FD_ISSET( sd, &ps.rws.socket_mask ) )
01101d
+#endif
01101d
       {
01101d
          msg( LOG_ERR, func,
01101d
 "Active single-threaded service %s: no server running, descriptor not set",
01101d
@@ -340,7 +429,11 @@ static unsigned thread_check( struct ser
01101d
       }
01101d
    }
01101d
    else
01101d
+#ifdef HAVE_POLL
01101d
+      if ( ! pfd->events )
01101d
+#else
01101d
       if ( ! FD_ISSET( sd, &ps.rws.socket_mask ) )
01101d
+#endif
01101d
       {
01101d
          msg( LOG_ERR, func,
01101d
             "Active multi-threaded service %s: descriptor not set", sid ) ;
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/main.c xinetd-2.3.14-poll/xinetd/main.c
01101d
--- xinetd-2.3.14-orig/xinetd/main.c	2009-07-27 13:27:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/main.c	2009-09-03 16:23:11.000000000 +0200
01101d
@@ -25,6 +25,9 @@
01101d
 #include "xtimer.h"
01101d
 #include "sensor.h"
01101d
 #include "xmdns.h"
01101d
+#ifdef HAVE_POLL
01101d
+#include "xpoll.h"
01101d
+#endif
01101d
 
01101d
 #ifdef __GNUC__
01101d
 __attribute__ ((noreturn))
01101d
@@ -119,16 +122,24 @@ static void main_loop(void)
01101d
 {
01101d
    const char      *func = "main_loop" ;
01101d
    struct timeval   tv, *tvptr = NULL;
01101d
+#ifdef HAVE_POLL
01101d
+   struct pollfd   *signal_pfd;
01101d
 
01101d
-   FD_SET(signals_pending[0], &ps.rws.socket_mask);
01101d
+   ps.rws.pfd_array[ps.rws.pfds_last].fd = signals_pending[0] ;
01101d
+   ps.rws.pfd_array[ps.rws.pfds_last].events = POLLIN ;
01101d
+   signal_pfd = &ps.rws.pfd_array[ps.rws.pfds_last] ;
01101d
+   ps.rws.pfds_last++;
01101d
+#else
01101d
+   FD_SET(signals_pending[0], &ps.rws.socket_mask) ;
01101d
    if ( signals_pending[0] > ps.rws.mask_max )
01101d
       ps.rws.mask_max = signals_pending[0] ;
01101d
-   if ( signals_pending[1] > ps.rws.mask_max )
01101d
-      ps.rws.mask_max = signals_pending[1] ;
01101d
+#endif /* HAVE_POLL */
01101d
 
01101d
    for ( ;; )
01101d
    {
01101d
+#ifndef HAVE_POLL
01101d
       fd_set read_mask ;
01101d
+#endif
01101d
       int n_active ;
01101d
       unsigned u ;
01101d
 
01101d
@@ -144,9 +155,14 @@ static void main_loop(void)
01101d
          tvptr = NULL;
01101d
       }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+      n_active = poll( ps.rws.pfd_array, ps.rws.pfds_last,
01101d
+                       tvptr == NULL ? -1 : tvptr->tv_sec*1000 ) ;
01101d
+#else
01101d
       read_mask = ps.rws.socket_mask ;
01101d
       n_active = select( ps.rws.mask_max+1, &read_mask,
01101d
                         FD_SET_NULL, FD_SET_NULL, tvptr ) ;
01101d
+#endif
01101d
       if ( n_active == -1 )
01101d
       {
01101d
          if ( errno == EINTR ) {
01101d
@@ -165,11 +181,27 @@ static void main_loop(void)
01101d
 
01101d
       xtimer_poll();
01101d
 
01101d
-      if( FD_ISSET(signals_pending[0], &read_mask) ) {
01101d
+#ifdef HAVE_POLL
01101d
+      if ( POLLFD_REVENTS( signal_pfd ) ) 
01101d
+      {
01101d
+        if ( POLLFD_REVENTS( signal_pfd ) & (POLLERR | POLLHUP | 
01101d
+            POLLNVAL) ) 
01101d
+          find_bad_fd();
01101d
+        else
01101d
+        {
01101d
+          check_pipe();
01101d
+          if ( --n_active == 0 )
01101d
+            continue ;
01101d
+        }
01101d
+      }
01101d
+#else
01101d
+      if( FD_ISSET(signals_pending[0], &read_mask) ) 
01101d
+      {
01101d
          check_pipe();
01101d
             if ( --n_active == 0 )
01101d
                continue ;
01101d
       }
01101d
+#endif
01101d
 
01101d
 #ifdef HAVE_MDNS
01101d
       if( xinetd_mdns_poll() == 0 )
01101d
@@ -186,19 +218,33 @@ static void main_loop(void)
01101d
          if ( ! SVC_IS_ACTIVE( sp ) )
01101d
             continue ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+         if ( SVC_REVENTS( sp ) )
01101d
+         {
01101d
+           if ( SVC_REVENTS( sp ) & (POLLERR | POLLHUP | 
01101d
+               POLLNVAL) ) 
01101d
+             find_bad_fd();
01101d
+           else
01101d
+           {
01101d
+             svc_request( sp ) ;
01101d
+             if ( --n_active == 0 )
01101d
+               break ;
01101d
+           }
01101d
+         }
01101d
+#else
01101d
          if ( FD_ISSET( SVC_FD( sp ), &read_mask ) )
01101d
          {
01101d
             svc_request( sp ) ;
01101d
             if ( --n_active == 0 )
01101d
                break ;
01101d
          }
01101d
+#endif
01101d
       }
01101d
       if ( n_active > 0 )
01101d
          msg( LOG_ERR, func, "%d descriptors still set", n_active ) ;
01101d
    }
01101d
 }
01101d
 
01101d
-
01101d
 /*
01101d
  * This function identifies if any of the fd's in the socket mask
01101d
  * is bad. We use it in case select(2) returns EBADF
01101d
@@ -208,13 +254,29 @@ static void main_loop(void)
01101d
 static void find_bad_fd(void)
01101d
 {
01101d
    int fd ;
01101d
+#ifdef HAVE_POLL
01101d
+   const char *reason;
01101d
+#else
01101d
    struct stat st ;
01101d
+#endif
01101d
    unsigned bad_fd_count = 0 ;
01101d
    const char *func = "find_bad_fd" ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   for ( fd = 0 ; (unsigned)fd < ps.rws.pfds_last ; fd++ )
01101d
+      if ( ps.rws.pfd_array[fd].revents & ( POLLHUP|POLLNVAL|POLLERR ) )
01101d
+      {
01101d
+         if ( ps.rws.pfd_array[fd].revents & POLLHUP )
01101d
+            reason = "hung up";
01101d
+         else if ( ps.rws.pfd_array[fd].revents & POLLNVAL )
01101d
+            reason = "been closed";
01101d
+         else if ( ps.rws.pfd_array[fd].revents & POLLERR )
01101d
+            reason = "reported error condition";
01101d
+#else
01101d
    for ( fd = 0 ; (unsigned)fd < ps.ros.max_descriptors ; fd++ )
01101d
       if ( FD_ISSET( fd, &ps.rws.socket_mask ) && fstat( fd, &st ) == -1 )
01101d
       {
01101d
+#endif
01101d
          int found = FALSE ;
01101d
          unsigned u ;
01101d
 
01101d
@@ -239,7 +301,11 @@ static void find_bad_fd(void)
01101d
          }
01101d
          if ( ! found )
01101d
          {
01101d
+#ifdef HAVE_POLL
01101d
+            ps.rws.pfd_array[fd].events = 0;
01101d
+#else
01101d
             FD_CLR( fd, &ps.rws.socket_mask ) ;
01101d
+#endif
01101d
             msg( LOG_ERR, func,
01101d
                "No active service for file descriptor %d\n", fd ) ;
01101d
             bad_fd_count++ ;
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/redirect.c xinetd-2.3.14-poll/xinetd/redirect.c
01101d
--- xinetd-2.3.14-orig/xinetd/redirect.c	2009-07-27 13:27:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/redirect.c	2009-09-02 16:00:34.000000000 +0200
01101d
@@ -58,14 +58,19 @@ void redir_handler( struct server *serp 
01101d
    struct service *sp = SERVER_SERVICE( serp );
01101d
    struct service_config *scp = SVC_CONF( sp );
01101d
    int RedirDescrip = SERVER_FD( serp );
01101d
-   int maxfd;
01101d
    ssize_t num_read, num_wrote=0, ret=0;
01101d
    unsigned int sin_len = 0;
01101d
    unsigned long bytes_in = 0, bytes_out = 0;
01101d
    int no_to_nagle = 1;
01101d
    int on = 1, v6on;
01101d
    char buff[NET_BUFFER];
01101d
+#ifdef HAVE_POLL
01101d
+   struct pollfd *pfd_array;
01101d
+   int            pfds_last = 0;
01101d
+#else
01101d
    fd_set rdfd, msfd;
01101d
+   int maxfd;
01101d
+#endif
01101d
    struct timeval *timep = NULL;
01101d
    const char *func = "redir_handler";
01101d
    union xsockaddr serveraddr ;
01101d
@@ -141,19 +146,43 @@ void redir_handler( struct server *serp 
01101d
          msg(LOG_ERR, func, "setsockopt RedirDescrip failed: %m");
01101d
       }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+#define REDIR_DESCRIP_INDEX 0
01101d
+#define REDIR_SERVER_INDEX 1
01101d
+      pfd_array = (struct pollfd *)calloc(sizeof(struct pollfd),INIT_POLLFDS);
01101d
+      if (pfd_array == NULL)
01101d
+      {
01101d
+         msg( LOG_ERR, func, "Cannot allocate memory for file descriptors!\n");
01101d
+         exit( 1 );
01101d
+      }
01101d
+      pfd_array[ REDIR_DESCRIP_INDEX ].fd = RedirDescrip;
01101d
+      pfd_array[ REDIR_DESCRIP_INDEX ].events = POLLIN;
01101d
+      pfd_array[ REDIR_SERVER_INDEX ].fd = RedirServerFd;
01101d
+      pfd_array[ REDIR_SERVER_INDEX ].events = POLLIN;
01101d
+      pfds_last += 2;
01101d
+#else
01101d
       maxfd = (RedirServerFd > RedirDescrip)?RedirServerFd:RedirDescrip;
01101d
       FD_ZERO(&msfd);
01101d
       FD_SET(RedirDescrip, &msfd);
01101d
       FD_SET(RedirServerFd, &msfd);
01101d
+#endif
01101d
 
01101d
       while(1) {
01101d
+#ifdef HAVE_POLL
01101d
+         if ( poll( pfd_array, pfds_last, -1 ) <= 0 ) {
01101d
+#else
01101d
          memcpy(&rdfd, &msfd, sizeof(rdfd));
01101d
          if (select(maxfd + 1, &rdfd, (fd_set *)0, (fd_set *)0, timep) <= 0) {
01101d
+#endif
01101d
             /* place for timeout code, currently does not time out */
01101d
             break;
01101d
          }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+         if ( pfd_array[REDIR_DESCRIP_INDEX].revents ) {
01101d
+#else
01101d
          if (FD_ISSET(RedirDescrip, &rdfd)) {
01101d
+#endif
01101d
             do {
01101d
                num_read = read(RedirDescrip,
01101d
                   buff, sizeof(buff));
01101d
@@ -179,7 +208,11 @@ void redir_handler( struct server *serp 
01101d
             }
01101d
          }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+         if ( pfd_array[REDIR_SERVER_INDEX].revents ) {
01101d
+#else
01101d
          if (FD_ISSET(RedirServerFd, &rdfd)) {
01101d
+#endif
01101d
             do {
01101d
                num_read = read(RedirServerFd,
01101d
                   buff, sizeof(buff));
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/server.c xinetd-2.3.14-poll/xinetd/server.c
01101d
--- xinetd-2.3.14-orig/xinetd/server.c	2005-03-29 17:50:34.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/server.c	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -298,7 +298,11 @@ void server_end( struct server *serp )
01101d
       
01101d
       /* Added this for when accepting wait=yes services */
01101d
       if( SVC_WAITS( sp ) )
01101d
+#ifdef HAVE_POLL
01101d
+         SVC_EVENTS( sp ) = POLLIN ;
01101d
+#else
01101d
          FD_SET( SVC_FD( sp ), &ps.rws.socket_mask ) ;
01101d
+#endif /* HAVE_POLL */
01101d
 
01101d
       svc_postmortem( sp, serp ) ;
01101d
       server_release( serp ) ;
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/service.c xinetd-2.3.14-poll/xinetd/service.c
01101d
--- xinetd-2.3.14-orig/xinetd/service.c	2009-07-27 13:27:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/service.c	2009-09-02 17:03:49.000000000 +0200
01101d
@@ -71,8 +71,6 @@ static const struct name_value service_s
01101d
       { "BAD STATE",          0                        }
01101d
    } ;
01101d
 
01101d
-
01101d
-
01101d
 /*
01101d
  * Allocate a new struct service and initialize it from scp 
01101d
  */
01101d
@@ -115,6 +113,10 @@ struct service *svc_make_special( struct
01101d
 
01101d
 void svc_free( struct service *sp )
01101d
 {
01101d
+#ifdef HAVE_POLL
01101d
+   *SVC_POLLFD( sp ) = ps.rws.pfd_array[--ps.rws.pfds_last] ;
01101d
+#endif /* HAVE_POLL */
01101d
+
01101d
    sc_free( SVC_CONF(sp) ) ;
01101d
    CLEAR( *sp ) ;
01101d
    FREE_SVC( sp ) ;
01101d
@@ -325,6 +327,25 @@ status_e svc_activate( struct service *s
01101d
       return( OK );
01101d
    }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   if ( ps.rws.pfds_last >= ps.rws.pfds_allocated )
01101d
+   {
01101d
+     int pos;
01101d
+     ps.rws.pfds_allocated += INIT_POLLFDS;
01101d
+     struct pollfd *tmp = (struct pollfd *)realloc( ps.rws.pfd_array,
01101d
+       ps.rws.pfds_allocated*sizeof(struct pollfd));
01101d
+     if ( tmp == NULL )
01101d
+     {
01101d
+       out_of_memory( func );
01101d
+       return( FAILED );
01101d
+     }
01101d
+     memset(&ps.rws.pfd_array[ps.rws.pfds_last], 0, (ps.rws.pfds_allocated-
01101d
+       ps.rws.pfds_last)*sizeof(struct pollfd));
01101d
+     ps.rws.pfd_array = tmp;
01101d
+   }
01101d
+   SVC_POLLFD( sp ) = &ps.rws.pfd_array[ps.rws.pfds_last++] ;
01101d
+#endif /* HAVE_POLL */
01101d
+
01101d
    if( SC_IPV4( scp ) ) {
01101d
       SVC_FD(sp) = socket( AF_INET, 
01101d
                            SC_SOCKET_TYPE( scp ), SC_PROTOVAL( scp ) ) ;
01101d
@@ -390,9 +411,14 @@ status_e svc_activate( struct service *s
01101d
 
01101d
    SVC_STATE(sp) = SVC_ACTIVE ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   SVC_EVENTS( sp ) = POLLIN ;
01101d
+#else
01101d
    FD_SET( SVC_FD(sp), &ps.rws.socket_mask ) ;
01101d
+
01101d
    if ( SVC_FD(sp) > ps.rws.mask_max )
01101d
       ps.rws.mask_max = SVC_FD(sp) ;
01101d
+#endif /* HAVE_POLL */
01101d
 
01101d
    ps.rws.active_services++ ;
01101d
    ps.rws.available_services++ ;
01101d
@@ -442,7 +468,11 @@ void svc_deactivate( struct service *sp 
01101d
 
01101d
    if ( SVC_IS_ACTIVE( sp ) )
01101d
    {
01101d
+#ifdef HAVE_POLL
01101d
+      SVC_EVENTS( sp ) = 0;
01101d
+#else      
01101d
       FD_CLR( SVC_FD( sp ), &ps.rws.socket_mask ) ;
01101d
+#endif /* HAVE_POLL */
01101d
       ps.rws.active_services-- ;
01101d
    }
01101d
 
01101d
@@ -465,7 +495,15 @@ void svc_suspend( struct service *sp )
01101d
       return ;
01101d
    }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   /* 
01101d
+    * don't reap the pfd from pfd_array, since we must have it allocated for
01101d
+    * SVC_FD( sp )
01101d
+    */
01101d
+   SVC_EVENTS( sp ) = 0;
01101d
+#else
01101d
    FD_CLR( SVC_FD( sp ), &ps.rws.socket_mask ) ;
01101d
+#endif
01101d
    ps.rws.active_services-- ;
01101d
    if ( debug.on )
01101d
       msg( LOG_DEBUG, func, "Suspended service %s", SVC_ID( sp ) ) ;
01101d
@@ -481,7 +519,12 @@ void svc_resume( struct service *sp )
01101d
 {
01101d
    const char *func = "svc_resume" ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   SVC_EVENTS( sp ) = POLLIN ;
01101d
+#else
01101d
    FD_SET( SVC_FD( sp ), &ps.rws.socket_mask ) ;
01101d
+#endif
01101d
+
01101d
    ps.rws.active_services++ ;
01101d
    if ( debug.on )
01101d
       msg( LOG_DEBUG, func, "Resumed service %s", SVC_ID( sp ) ) ;
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/service.h xinetd-2.3.14-poll/xinetd/service.h
01101d
--- xinetd-2.3.14-orig/xinetd/service.h	2005-03-29 17:50:34.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/service.h	2009-09-03 16:24:16.000000000 +0200
01101d
@@ -17,6 +17,9 @@
01101d
 #include "pset.h"
01101d
 #include "xlog.h"
01101d
 #include "server.h"
01101d
+#ifdef HAVE_POLL
01101d
+#include "xpoll.h"
01101d
+#endif
01101d
 
01101d
 /*
01101d
  * $Id: service.h,v 1.6 2012-05-09 15:40:29 bbraun Exp $
01101d
@@ -45,7 +48,13 @@ struct service
01101d
    state_e                svc_state ;
01101d
    int                    svc_ref_count ;   /* # of pters to this struct */
01101d
    struct service_config *svc_conf ;    /* service configuration */
01101d
+
01101d
+#ifdef HAVE_POLL
01101d
+   struct pollfd         *svc_pfd ;  /* pointer to the pollfd */
01101d
+#else
01101d
    int                    svc_fd ;	/* The Listening FD for the service */
01101d
+#endif /* HAVE_POLL */
01101d
+
01101d
    unsigned               svc_running_servers ;
01101d
    unsigned               svc_retry_servers ;
01101d
    unsigned               svc_attempts ; /* # of attempts to start server */
01101d
@@ -70,7 +79,17 @@ struct service
01101d
  * Field access macros
01101d
  */
01101d
 #define SVC_CONF( sp )             ( (sp)->svc_conf )
01101d
+
01101d
+#ifdef HAVE_POLL
01101d
+#define SVC_POLLFD( sp )           ( (sp)->svc_pfd )
01101d
+#define SVC_POLLFD_OFF( sp )       ( SVC_POLLFD( sp )-ps.rws.pfd_array )
01101d
+#define SVC_EVENTS( sp )           ( POLLFD_EVENTS( SVC_POLLFD( sp ) ) )
01101d
+#define SVC_REVENTS( sp )          ( POLLFD_REVENTS( SVC_POLLFD( sp ) ) )
01101d
+#define SVC_FD( sp )               ( POLLFD_FD( SVC_POLLFD( sp ) ) )
01101d
+#else
01101d
 #define SVC_FD( sp )               ( (sp)->svc_fd )
01101d
+#endif /* HAVE_POLL */
01101d
+
01101d
 #define SVC_RUNNING_SERVERS( sp )  (sp)->svc_running_servers
01101d
 #define SVC_RETRIES( sp )          (sp)->svc_retry_servers
01101d
 #define SVC_LOG( sp )              (sp)->svc_log
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/state.h xinetd-2.3.14-poll/xinetd/state.h
01101d
--- xinetd-2.3.14-orig/xinetd/state.h	2005-03-31 01:15:28.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/state.h	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -21,7 +21,10 @@
01101d
 #endif
01101d
 #include "libportable.h"
01101d
 
01101d
-#ifdef HAVE_SYS_SELECT_H
01101d
+#ifdef HAVE_POLL
01101d
+#include <poll.h>
01101d
+#endif
01101d
+#if HAVE_SYS_SELECT_H
01101d
 #include <sys/select.h>
01101d
 #endif
01101d
 
01101d
@@ -32,7 +35,6 @@
01101d
 
01101d
 struct read_only_state
01101d
 {
01101d
-   rlim_t      orig_max_descriptors ; /* original soft rlimit                */
01101d
    rlim_t      max_descriptors ;      /* original hard rlimit or OPEN_MAX    */
01101d
    rlim_t      process_limit ;        /* if 0, there is no limit             */
01101d
    int         cc_interval ;          /* # of seconds the cc gets invoked.   */
01101d
@@ -58,8 +60,15 @@ struct read_write_state
01101d
    int              available_services ;   /* # of available services       */
01101d
    int              active_services ;      /* services with descriptors set */
01101d
                                            /* in socket mask                */
01101d
+#ifdef HAVE_POLL 
01101d
+   struct pollfd   *pfd_array;             /* array passed to poll(2)       */
01101d
+   int              pfds_last;             /* index of last fd in the array */
01101d
+   int              pfds_allocated;        /* size of the array             */
01101d
+#else
01101d
    fd_set           socket_mask ;
01101d
    int              mask_max ;
01101d
+#endif /* HAVE_POLL */
01101d
+
01101d
    pset_h           servers ;              /* table of running servers      */
01101d
    pset_h           retries ;              /* table of servers to retry     */
01101d
    pset_h           services ;             /* table of services             */
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/tcpint.c xinetd-2.3.14-poll/xinetd/tcpint.c
01101d
--- xinetd-2.3.14-orig/xinetd/tcpint.c	2009-07-27 13:27:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/tcpint.c	2009-09-02 16:49:32.000000000 +0200
01101d
@@ -63,7 +63,15 @@ struct intercept_s *si_init( struct serv
01101d
    return( ip ) ;
01101d
 }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+static status_e handle_io( psi_h iter, channel_s *chp,
01101d
+                           struct pollfd *pfd_handled,
01101d
+                           struct pollfd *pfd_array,
01101d
+                           int *pfds_last,
01101d
+                           stream_status_e (*iofunc)() );
01101d
+#else
01101d
 static status_e handle_io( psi_h iter, channel_s *chp, fd_set *maskp, stream_status_e (*iofunc)() );
01101d
+#endif
01101d
 static stream_status_e tcp_local_to_remote( channel_s *chp );
01101d
 static stream_status_e tcp_remote_to_local( channel_s *chp );
01101d
 static void connection_request( struct intercept_s *ip, channel_s **chpp );
01101d
@@ -82,14 +90,26 @@ void si_exit(void)
01101d
 static void si_mux(void)
01101d
 {
01101d
    struct intercept_s   *ip = &stream_intercept_state ;
01101d
+#ifdef HAVE_POLL
01101d
+   struct pollfd        *pfd_array;
01101d
+   int                   pfds_last = 0;
01101d
+   int                   pfds_allocated = INIT_POLLFDS;
01101d
+#else
01101d
    fd_set                     socket_mask ;
01101d
    int                        mask_max ;
01101d
+#endif
01101d
    psi_h                      iter ;
01101d
    const char                *func = "si_mux" ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   pfd_array = calloc(sizeof(struct pollfd),INIT_POLLFDS);
01101d
+   pfd_array[ pfds_last ].fd = INT_REMOTE( ip ) ;
01101d
+   pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT;
01101d
+#else
01101d
    FD_ZERO( &socket_mask ) ;
01101d
    FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
01101d
    mask_max = INT_REMOTE( ip ) ;
01101d
+#endif
01101d
 
01101d
    iter = psi_create( INT_CONNECTIONS( ip ) ) ;
01101d
    if ( iter == NULL )
01101d
@@ -101,26 +121,43 @@ static void si_mux(void)
01101d
    for ( ;; )
01101d
    {
01101d
       channel_s *chp ;
01101d
+#ifndef HAVE_POLL
01101d
       fd_set read_mask ;
01101d
+#endif
01101d
       int n_ready ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+      n_ready = int_poll( pfds_last, pfd_array ) ;
01101d
+#else
01101d
       read_mask = socket_mask ;
01101d
       n_ready = int_select( mask_max+1, &read_mask ) ;
01101d
+#endif
01101d
 
01101d
       if ( n_ready == -1 )
01101d
          return ;
01101d
       
01101d
+#ifdef HAVE_POLL
01101d
+      if ( pfd_array[0].revents & ( POLLIN | POLLOUT ) )
01101d
+#else
01101d
       if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
01101d
+#endif
01101d
       {
01101d
          connection_request( ip, &chp ) ;
01101d
          if ( chp != NULL )
01101d
          {
01101d
+#ifdef HAVE_POLL
01101d
+            pfd_array[ pfds_last ].fd = chp->ch_local_socket ;
01101d
+            pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT ;
01101d
+            pfd_array[ pfds_last ].fd = chp->ch_remote_socket ;
01101d
+            pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT ;
01101d
+#else
01101d
             FD_SET( chp->ch_local_socket, &socket_mask ) ;
01101d
             if ( chp->ch_local_socket > mask_max )
01101d
                mask_max = chp->ch_local_socket ;
01101d
             FD_SET( chp->ch_remote_socket, &socket_mask ) ;
01101d
             if ( chp->ch_remote_socket > mask_max )
01101d
                mask_max = chp->ch_remote_socket ;
01101d
+#endif
01101d
          }
01101d
          if ( --n_ready == 0 )
01101d
             continue ;
01101d
@@ -128,27 +165,57 @@ static void si_mux(void)
01101d
 
01101d
       for ( chp = CHP( psi_start(iter) ) ; chp ; chp = CHP( psi_next(iter) ) )
01101d
       {
01101d
+#ifdef HAVE_POLL
01101d
+         int i;
01101d
+         struct pollfd *local_pfd = NULL, *remote_pfd = NULL;
01101d
+
01101d
+         /* TODO: detection with O(n)=1 */
01101d
+         for (i = 0 ; i < pfds_last ; i++ )
01101d
+           if (pfd_array[i].fd == chp->ch_local_socket)
01101d
+             local_pfd = &pfd_array[i];
01101d
+           else if (pfd_array[i] .fd== chp->ch_remote_socket)
01101d
+             remote_pfd = &pfd_array[i];
01101d
+
01101d
+         if ( local_pfd != NULL && 
01101d
+              local_pfd->revents & ( POLLIN | POLLOUT) )
01101d
+#else
01101d
          if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
01101d
+#endif
01101d
          {
01101d
 #ifdef DEBUG_TCPINT
01101d
             if ( debug.on )
01101d
                msg( LOG_DEBUG, func, "Input available on local socket %d", 
01101d
                                                          chp->ch_local_socket ) ;
01101d
 #endif
01101d
+#ifdef HAVE_POLL
01101d
+            if ( handle_io( iter, chp, local_pfd, pfd_array,
01101d
+                    &pfds_last, tcp_local_to_remote ) == FAILED )
01101d
+#else
01101d
             if ( handle_io( iter, chp, &socket_mask, tcp_local_to_remote ) == FAILED )
01101d
+#endif
01101d
                return ;
01101d
             if ( --n_ready == 0 )
01101d
                break ;
01101d
          }
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+         if ( remote_pfd != NULL && 
01101d
+              remote_pfd->revents & ( POLLIN | POLLOUT) )
01101d
+#else
01101d
          if ( FD_ISSET( chp->ch_remote_socket, &read_mask ) )
01101d
+#endif
01101d
          {
01101d
 #ifdef DEBUG_TCPINT
01101d
             msg( LOG_DEBUG, func, "Input available on remote socket %d", 
01101d
                                                       chp->ch_remote_socket ) ;
01101d
 #endif
01101d
+#ifdef HAVE_POLL
01101d
+            if ( handle_io( iter, chp, remote_pfd, pfd_array,
01101d
+                    &pfds_last, tcp_local_to_remote ) == FAILED )
01101d
+#else
01101d
             if ( handle_io( iter, chp,
01101d
                         &socket_mask, tcp_remote_to_local ) == FAILED )
01101d
+#endif
01101d
                return ;
01101d
             if ( --n_ready == 0 )
01101d
                break ;
01101d
@@ -158,10 +225,19 @@ static void si_mux(void)
01101d
 }
01101d
 
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+static status_e handle_io( psi_h iter, 
01101d
+                            channel_s *chp, 
01101d
+                            struct pollfd *pfd_handled,
01101d
+                            struct pollfd *pfd_array,
01101d
+                            int *pfds_last,
01101d
+                            stream_status_e (*iofunc)() )
01101d
+#else
01101d
 static status_e handle_io( psi_h iter, 
01101d
                             channel_s *chp, 
01101d
                             fd_set *maskp, 
01101d
                             stream_status_e (*iofunc)() )
01101d
+#endif
01101d
 {
01101d
    const char *func = "handle_io" ;
01101d
 
01101d
@@ -178,8 +254,13 @@ static status_e handle_io( psi_h iter, 
01101d
                   xaddrname( &chp->ch_from ), ntohs(xaddrport( &chp->ch_from )),
01101d
                         chp->ch_local_socket, chp->ch_remote_socket ) ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+         if ( pfd_handled != NULL)
01101d
+           *pfd_handled = pfd_array[ --( *pfds_last ) ];
01101d
+#else
01101d
          FD_CLR( chp->ch_local_socket, maskp ) ;
01101d
          FD_CLR( chp->ch_remote_socket, maskp ) ;
01101d
+#endif
01101d
          (void) Sclose( chp->ch_remote_socket ) ;
01101d
          (void) Sclose( chp->ch_local_socket ) ;
01101d
          psi_remove( iter ) ;
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/udpint.c xinetd-2.3.14-poll/xinetd/udpint.c
01101d
--- xinetd-2.3.14-orig/xinetd/udpint.c	2009-07-27 13:27:59.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/udpint.c	2009-09-02 16:59:33.000000000 +0200
01101d
@@ -15,6 +15,9 @@
01101d
 #include <syslog.h>
01101d
 #include <errno.h>
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+#include <poll.h>
01101d
+#endif
01101d
 #ifdef HAVE_SYS_SELECT_H
01101d
 #include <sys/select.h>
01101d
 #endif
01101d
@@ -97,34 +100,61 @@ void di_exit(void)
01101d
 static void di_mux(void)
01101d
 {
01101d
    struct intercept_s   *ip = &dgram_intercept_state ;
01101d
+#ifdef HAVE_POLL
01101d
+   struct pollfd        *pfd_array;
01101d
+   int                   pfds_last = 0;
01101d
+   int                   pfds_allocated = INIT_POLLFDS;
01101d
+#else
01101d
    fd_set                     socket_mask ;
01101d
    int                        mask_max ;
01101d
+#endif
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+   pfd_array = (struct pollfd *)calloc(sizeof(struct pollfd),INIT_POLLFDS);
01101d
+   pfd_array[ pfds_last ].fd = INT_REMOTE( ip );
01101d
+   pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT;
01101d
+#else
01101d
    FD_ZERO( &socket_mask ) ;
01101d
    FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
01101d
    mask_max = INT_REMOTE( ip ) ;
01101d
+#endif
01101d
 
01101d
    for ( ;; )
01101d
    {
01101d
       unsigned u ;
01101d
       channel_s *chp ;
01101d
+#ifndef HAVE_POLL
01101d
       fd_set read_mask ;
01101d
+#endif
01101d
       int n_ready ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+      n_ready = int_poll( pfds_last, pfd_array ) ;
01101d
+#else
01101d
       read_mask = socket_mask ;
01101d
       n_ready = int_select( mask_max+1, &read_mask ) ;
01101d
+#endif
01101d
 
01101d
       if ( n_ready == -1 )
01101d
          return ;
01101d
       
01101d
+#ifdef HAVE_POLL
01101d
+      if ( pfd_array[0].revents & ( POLLIN | POLLOUT ) )
01101d
+#else
01101d
       if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
01101d
+#endif
01101d
       {
01101d
          udp_remote_to_local( ip, &chp ) ;
01101d
          if ( chp != NULL )
01101d
          {
01101d
+#ifdef HAVE_POLL
01101d
+            pfd_array[ pfds_last ].fd = chp->ch_local_socket ;
01101d
+            pfd_array[ pfds_last++ ].events = POLLIN | POLLOUT ;
01101d
+#else
01101d
             FD_SET( chp->ch_local_socket, &socket_mask ) ;
01101d
             if ( chp->ch_local_socket > mask_max )
01101d
                mask_max = chp->ch_local_socket ;
01101d
+#endif
01101d
          }
01101d
          if ( --n_ready == 0 )
01101d
             continue ;
01101d
@@ -134,7 +164,17 @@ static void di_mux(void)
01101d
       {
01101d
          chp = CHP( pset_pointer( INT_CONNECTIONS( ip ), u ) ) ;
01101d
 
01101d
+#ifdef HAVE_POLL
01101d
+         int i;
01101d
+         /* TODO: detection with O(n)=1 */
01101d
+         for (i = 0 ; i < pfds_last ; i++)
01101d
+           if (pfd_array[i].fd == chp->ch_local_socket)
01101d
+             break;
01101d
+         if (pfd_array[i].fd == chp->ch_local_socket &&
01101d
+             (pfd_array[i].revents & ( POLLIN | POLLOUT )))
01101d
+#else
01101d
          if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
01101d
+#endif
01101d
          {
01101d
             if ( udp_local_to_remote( chp ) == FAILED )
01101d
                return ;
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/xmdns.c xinetd-2.3.14-poll/xinetd/xmdns.c
01101d
--- xinetd-2.3.14-orig/xinetd/xmdns.c	2005-04-08 23:23:07.000000000 +0200
01101d
+++ xinetd-2.3.14-poll/xinetd/xmdns.c	2009-09-02 17:01:54.000000000 +0200
01101d
@@ -109,7 +109,26 @@ int xinetd_mdns_init(void) {
01101d
       ps.rws.mdns_state = NULL;
01101d
       return -1;
01101d
    }
01101d
+#ifdef HAVE_POLL
01101d
+   if ( ps.rws.pfds_last >= ps.rws.pfds_allocated )
01101d
+   {
01101d
+     ps.rws.pfds_allocated += INIT_POLLFDS;
01101d
+     struct pollfd *tmp = (struct pollfd *)realloc( ps.rws.pfd_array,
01101d
+         ps.rws.pfds_allocated*sizeof(struct pollfd));
01101d
+     if ( tmp == NULL )
01101d
+     {
01101d
+       out_of_memory( func );
01101d
+       return -1;
01101d
+     }
01101d
+     memset(&ps.rws.pfd_array[ps.rws.pfds_last], 0, (ps.rws.pfds_allocated-
01101d
+           ps.rws.pfds_last)*sizeof(struct pollfd));
01101d
+     ps.rws.pfd_array = tmp;
01101d
+   }
01101d
+   ps.rws.pfd_array[ ps.rws.pfds_last ].fd = sw_discovery_socket(*(sw_discovery *)ps.rws.mdns_state);
01101d
+   ps.rws.pfd_array[ ps.rws.pfds_last++ ].events = POLLIN;
01101d
+#else
01101d
    FD_SET( sw_discovery_socket(*(sw_discovery *)ps.rws.mdns_state), &ps.rws.socket_mask ) ;
01101d
+#endif
01101d
    return 0;
01101d
 #endif
01101d
 }
01101d
diff -Nurp xinetd-2.3.14-orig/xinetd/xpoll.h xinetd-2.3.14-poll/xinetd/xpoll.h
01101d
--- xinetd-2.3.14-orig/xinetd/xpoll.h	1970-01-01 01:00:00.000000000 +0100
01101d
+++ xinetd-2.3.14-poll/xinetd/xpoll.h	2009-09-02 11:30:27.000000000 +0200
01101d
@@ -0,0 +1,23 @@
01101d
+/*
01101d
+ * (c) Copyright 2009 by Red Hat Inc.
01101d
+ * All rights reserved.  The file named COPYRIGHT specifies the terms 
01101d
+ * and conditions for redistribution.
01101d
+ */
01101d
+#include "config.h"
01101d
+#ifdef HAVE_POLL
01101d
+#ifndef _X_POLL_H
01101d
+#define _X_POLL_H
01101d
+
01101d
+#include <poll.h>
01101d
+#include "defs.h"
01101d
+
01101d
+
01101d
+/* Field accessor methods for pollfd in defined in poll.h */
01101d
+#define POLLFD_FD( pfd )           ( (pfd)->fd )
01101d
+#define POLLFD_EVENTS( pfd )       ( (pfd)->events )
01101d
+#define POLLFD_REVENTS( pfd )      ( (pfd)->revents )
01101d
+
01101d
+/* TODO: write memory management stuff in xpoll.c if needed */
01101d
+
01101d
+#endif /* _X_POLL_H */
01101d
+#endif /* HAVE_POLL */