Use poll() instead of select() to remove limits on open file descriptors.
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index fd24f63..514e10b 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -24,8 +24,8 @@
 static volatile pid_t pid = 0;
 static volatile int pipewrite;
 
-static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp);
-static void check_dns_listeners(fd_set *set, time_t now);
+static int set_dns_listeners(time_t now);
+static void check_dns_listeners(time_t now);
 static void sig_handler(int sig);
 static void async_event(int pipe, time_t now);
 static void fatal_event(struct event_desc *ev, char *msg);
@@ -799,10 +799,6 @@
   if (option_bool(OPT_TFTP))
     {
       struct tftp_prefix *p;
-#ifdef FD_SETSIZE
-      if (FD_SETSIZE < (unsigned)max_fd)
-	max_fd = FD_SETSIZE;
-#endif
 
       my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s", 
 		daemon->tftp_prefix ? _("root is ") : _("enabled"),
@@ -862,72 +858,58 @@
   
   while (1)
     {
-      int maxfd = -1;
-      struct timeval t, *tp = NULL;
-      fd_set rset, wset, eset;
+      int t, timeout = -1;
       
-      FD_ZERO(&rset);
-      FD_ZERO(&wset);
-      FD_ZERO(&eset);
+      poll_reset();
       
       /* if we are out of resources, find how long we have to wait
 	 for some to come free, we'll loop around then and restart
 	 listening for queries */
-      if ((t.tv_sec = set_dns_listeners(now, &rset, &maxfd)) != 0)
-	{
-	  t.tv_usec = 0;
-	  tp = &t;
-	}
+      if ((t = set_dns_listeners(now)) != 0)
+	timeout = t * 1000;
 
       /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
       if (daemon->tftp_trans ||
 	  (option_bool(OPT_DBUS) && !daemon->dbus))
-	{
-	  t.tv_sec = 0;
-	  t.tv_usec = 250000;
-	  tp = &t;
-	}
+	timeout = 250;
+
       /* Wake every second whilst waiting for DAD to complete */
       else if (is_dad_listeners())
-	{
-	  t.tv_sec = 1;
-	  t.tv_usec = 0;
-	  tp = &t;
-	}
+	timeout = 1000;
 
 #ifdef HAVE_DBUS
-      set_dbus_listeners(&maxfd, &rset, &wset, &eset);
+      set_dbus_listeners();
 #endif	
   
 #ifdef HAVE_DHCP
       if (daemon->dhcp || daemon->relay4)
 	{
-	  bump_maxfd(&rset, daemon->dhcpfd, &maxfd);
+	  poll_listen(daemon->dhcpfd, POLLIN);
 	  if (daemon->pxefd != -1)
-	    bump_maxfd(&rset, daemon->pxefd, &maxfd);
+	    poll_listen(daemon->pxefd, POLLIN);
 	}
 #endif
 
 #ifdef HAVE_DHCP6
       if (daemon->doing_dhcp6 || daemon->relay6)
-	bump_maxfd(&rset, daemon->dhcp6fd, &maxfd);
+	poll_listen(daemon->dhcp6fd, POLLIN);
 	
       if (daemon->doing_ra)
-	bump_maxfd(&rset, daemon->icmp6fd, &maxfd); 
+	poll_listen(daemon->icmp6fd, POLLIN); 
 #endif
     
 #ifdef HAVE_INOTIFY
       if (daemon->inotifyfd != -1)
-	bump_maxfd(&rset, daemon->inotifyfd, &maxfd);
+	poll_listen(daemon->inotifyfd, POLLIN);
 #endif
 
 #if defined(HAVE_LINUX_NETWORK)
-      bump_maxfd(&rset, daemon->netlinkfd, &maxfd);
+      poll_listen(daemon->netlinkfd, POLLIN);
 #elif defined(HAVE_BSD_NETWORK)
-      bump_maxfd(&rset, daemon->routefd, &maxfd);
+      poll_listen(daemon->routefd, POLLIN);
 #endif
       
-      bump_maxfd(&rset, piperead, &maxfd);
+      poll_listen(piperead, POLLIN);
 
 #ifdef HAVE_DHCP
 #  ifdef HAVE_SCRIPT
@@ -938,7 +920,7 @@
 #    endif
 
       if (!helper_buf_empty())
-	bump_maxfd(&wset, daemon->helperfd, &maxfd);
+	poll_listen(daemon->helperfd, POLLOUT);
 #  else
       /* need this for other side-effects */
       while (do_script_run(now));
@@ -952,17 +934,14 @@
    
       /* must do this just before select(), when we know no
 	 more calls to my_syslog() can occur */
-      set_log_writer(&wset, &maxfd);
+      set_log_writer();
       
-      if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
-	{
-	  /* otherwise undefined after error */
-	  FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
-	}
-
+      if (do_poll(timeout) < 0)
+	continue;
+      
       now = dnsmasq_time();
 
-      check_log_writer(&wset);
+      check_log_writer(0);
 
       /* prime. */
       enumerate_interfaces(1);
@@ -978,15 +957,15 @@
 	}
 
 #if defined(HAVE_LINUX_NETWORK)
-      if (FD_ISSET(daemon->netlinkfd, &rset))
+      if (poll_check(daemon->netlinkfd, POLLIN))
 	netlink_multicast();
 #elif defined(HAVE_BSD_NETWORK)
-      if (FD_ISSET(daemon->routefd, &rset))
+      if (poll_check(daemon->routefd, POLLIN))
 	route_sock();
 #endif
 
 #ifdef HAVE_INOTIFY
-      if  (daemon->inotifyfd != -1 && FD_ISSET(daemon->inotifyfd, &rset) && inotify_check(now))
+      if  (daemon->inotifyfd != -1 && poll_check(daemon->inotifyfd, POLLIN) && inotify_check(now))
 	{
 	  if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
 	    poll_resolv(1, 1, now);
@@ -1006,7 +985,7 @@
 	}
 #endif
 
-      if (FD_ISSET(piperead, &rset))
+      if (poll_check(piperead, POLLIN))
 	async_event(piperead, now);
       
 #ifdef HAVE_DBUS
@@ -1019,34 +998,34 @@
 	  if (daemon->dbus)
 	    my_syslog(LOG_INFO, _("connected to system DBus"));
 	}
-      check_dbus_listeners(&rset, &wset, &eset);
+      check_dbus_listeners();
 #endif
       
-      check_dns_listeners(&rset, now);
+      check_dns_listeners(now);
 
 #ifdef HAVE_TFTP
-      check_tftp_listeners(&rset, now);
+      check_tftp_listeners(now);
 #endif      
 
 #ifdef HAVE_DHCP
       if (daemon->dhcp || daemon->relay4)
 	{
-	  if (FD_ISSET(daemon->dhcpfd, &rset))
+	  if (poll_check(daemon->dhcpfd, POLLIN))
 	    dhcp_packet(now, 0);
-	  if (daemon->pxefd != -1 && FD_ISSET(daemon->pxefd, &rset))
+	  if (daemon->pxefd != -1 && poll_check(daemon->pxefd, POLLIN))
 	    dhcp_packet(now, 1);
 	}
 
 #ifdef HAVE_DHCP6
-      if ((daemon->doing_dhcp6 || daemon->relay6) && FD_ISSET(daemon->dhcp6fd, &rset))
+      if ((daemon->doing_dhcp6 || daemon->relay6) && poll_check(daemon->dhcp6fd, POLLIN))
 	dhcp6_packet(now);
 
-      if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset))
+      if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
 	icmp6_packet(now);
 #endif
 
 #  ifdef HAVE_SCRIPT
-      if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
+      if (daemon->helperfd != -1 && poll_check(daemon->helperfd, POLLIN))
 	helper_write();
 #  endif
 #endif
@@ -1451,7 +1430,7 @@
 #endif
 }
 
-static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
+static int set_dns_listeners(time_t now)
 {
   struct serverfd *serverfdp;
   struct listener *listener;
@@ -1463,7 +1442,7 @@
   for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
     {
       tftp++;
-      bump_maxfd(set, transfer->sockfd, maxfdp);
+      poll_listen(transfer->sockfd, POLLIN);
     }
 #endif
   
@@ -1472,18 +1451,18 @@
     get_new_frec(now, &wait, 0);
   
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
-    bump_maxfd(set, serverfdp->fd, maxfdp);
+    poll_listen(serverfdp->fd, POLLIN);
     
   if (daemon->port != 0 && !daemon->osport)
     for (i = 0; i < RANDOM_SOCKS; i++)
       if (daemon->randomsocks[i].refcount != 0)
-	bump_maxfd(set, daemon->randomsocks[i].fd, maxfdp);
+	poll_listen(daemon->randomsocks[i].fd, POLLIN);
 	  
   for (listener = daemon->listeners; listener; listener = listener->next)
     {
       /* only listen for queries if we have resources */
       if (listener->fd != -1 && wait == 0)
-	bump_maxfd(set, listener->fd, maxfdp);
+	poll_listen(listener->fd, POLLIN);
 	
       /* death of a child goes through the select loop, so
 	 we don't need to explicitly arrange to wake up here */
@@ -1491,13 +1470,13 @@
 	for (i = 0; i < MAX_PROCS; i++)
 	  if (daemon->tcp_pids[i] == 0)
 	    {
-	      bump_maxfd(set, listener->tcpfd, maxfdp);
+	      poll_listen(listener->tcpfd, POLLIN);
 	      break;
 	    }
 
 #ifdef HAVE_TFTP
       if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
-	bump_maxfd(set, listener->tftpfd, maxfdp);
+	poll_listen(listener->tftpfd, POLLIN);
 #endif
 
     }
@@ -1505,33 +1484,33 @@
   return wait;
 }
 
-static void check_dns_listeners(fd_set *set, time_t now)
+static void check_dns_listeners(time_t now)
 {
   struct serverfd *serverfdp;
   struct listener *listener;
   int i;
 
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
-    if (FD_ISSET(serverfdp->fd, set))
+    if (poll_check(serverfdp->fd, POLLIN))
       reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
   
   if (daemon->port != 0 && !daemon->osport)
     for (i = 0; i < RANDOM_SOCKS; i++)
       if (daemon->randomsocks[i].refcount != 0 && 
-	  FD_ISSET(daemon->randomsocks[i].fd, set))
+	  poll_check(daemon->randomsocks[i].fd, POLLIN))
 	reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
   
   for (listener = daemon->listeners; listener; listener = listener->next)
     {
-      if (listener->fd != -1 && FD_ISSET(listener->fd, set))
+      if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
 	receive_query(listener, now); 
       
 #ifdef HAVE_TFTP     
-      if (listener->tftpfd != -1 && FD_ISSET(listener->tftpfd, set))
+      if (listener->tftpfd != -1 && poll_check(listener->tftpfd, POLLIN))
 	tftp_request(listener, now);
 #endif
 
-      if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set))
+      if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
 	{
 	  int confd, client_ok = 1;
 	  struct irec *iface = NULL;
@@ -1772,51 +1751,41 @@
   for (now = start = dnsmasq_time(), timeout_count = 0; 
        (difftime(now, start) < (float)PING_WAIT) && (timeout_count < PING_WAIT * 4);)
     {
-      struct timeval tv;
-      fd_set rset, wset;
       struct sockaddr_in faddr;
-      int maxfd = fd; 
       socklen_t len = sizeof(faddr);
       
-      tv.tv_usec = 250000;
-      tv.tv_sec = 0; 
-      
-      FD_ZERO(&rset);
-      FD_ZERO(&wset);
-      FD_SET(fd, &rset);
-      set_dns_listeners(now, &rset, &maxfd);
-      set_log_writer(&wset, &maxfd);
+      poll_reset();
+      poll_listen(fd, POLLIN);
+      set_dns_listeners(now);
+      set_log_writer();
       
 #ifdef HAVE_DHCP6
       if (daemon->doing_ra)
-	bump_maxfd(&rset, daemon->icmp6fd, &maxfd); 
+	poll_listen(daemon->icmp6fd, POLLIN); 
 #endif
       
-      rc = select(maxfd+1, &rset, &wset, NULL, &tv);
+      rc = do_poll(250);
       
       if (rc < 0)
-	{
-	  FD_ZERO(&rset);
-	  FD_ZERO(&wset);
-	}
+	continue;
       else if (rc == 0)
 	timeout_count++;
 
       now = dnsmasq_time();
 
-      check_log_writer(&wset);
-      check_dns_listeners(&rset, now);
+      check_log_writer(0);
+      check_dns_listeners(now);
 
 #ifdef HAVE_DHCP6
-      if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset))
+      if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
 	icmp6_packet(now);
 #endif
       
 #ifdef HAVE_TFTP
-      check_tftp_listeners(&rset, now);
+      check_tftp_listeners(now);
 #endif
 
-      if (FD_ISSET(fd, &rset) &&
+      if (poll_check(fd, POLLIN) &&
 	  recvfrom(fd, &packet, sizeof(packet), 0,
 		   (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
 	  saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&