summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2015-07-12 21:09:11 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2015-07-12 21:09:11 +0100
commitb842bc97bb3bf1861f6fc01b01f5c673fc49cd35 (patch)
tree924a98c5f6e71252fdd4fccc0c19a09ca2f53424
parent0f38fa05a65b50dd4ee8d755a908416326e84f22 (diff)
downloaddnsmasq-2.74test2.tar.gz
Use poll() instead of select() to remove limits on open file descriptors.v2.74test2
-rw-r--r--Makefile2
-rw-r--r--bld/Android.mk2
-rw-r--r--src/dbus.c17
-rw-r--r--src/dnsmasq.c153
-rw-r--r--src/dnsmasq.h20
-rw-r--r--src/forward.c4
-rw-r--r--src/log.c8
-rw-r--r--src/poll.c124
-rw-r--r--src/tftp.c4
-rw-r--r--src/util.c19
10 files changed, 216 insertions, 137 deletions
diff --git a/Makefile b/Makefile
index 59750bc..4c87ea9 100644
--- a/Makefile
+++ b/Makefile
@@ -73,7 +73,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
- domain.o dnssec.o blockdata.o tables.o loop.o inotify.o
+ domain.o dnssec.o blockdata.o tables.o loop.o inotify.o poll.o
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h
diff --git a/bld/Android.mk b/bld/Android.mk
index d627796..5364ee7 100644
--- a/bld/Android.mk
+++ b/bld/Android.mk
@@ -10,7 +10,7 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
radv.c slaac.c auth.c ipset.c domain.c \
dnssec.c dnssec-openssl.c blockdata.c tables.c \
- loop.c inotify.c
+ loop.c inotify.c poll.c
LOCAL_MODULE := dnsmasq
diff --git a/src/dbus.c b/src/dbus.c
index 1384ccf..3555f49 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -749,8 +749,7 @@ char *dbus_init(void)
}
-void set_dbus_listeners(int *maxfdp,
- fd_set *rset, fd_set *wset, fd_set *eset)
+void set_dbus_listeners(void)
{
struct watch *w;
@@ -761,16 +760,16 @@ void set_dbus_listeners(int *maxfdp,
int fd = dbus_watch_get_unix_fd(w->watch);
if (flags & DBUS_WATCH_READABLE)
- bump_maxfd(rset, fd, maxfdp);
+ poll_listen(fd, POLLIN);
if (flags & DBUS_WATCH_WRITABLE)
- bump_maxfd(wset, fd, maxfdp);
+ poll_listen(fd, POLLOUT);
- bump_maxfd(eset, fd, maxfdp);
+ poll_listen(fd, POLLERR);
}
}
-void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
+void check_dbus_listeners()
{
DBusConnection *connection = (DBusConnection *)daemon->dbus;
struct watch *w;
@@ -781,13 +780,13 @@ void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
unsigned int flags = 0;
int fd = dbus_watch_get_unix_fd(w->watch);
- if (FD_ISSET(fd, rset))
+ if (poll_check(fd, POLLIN))
flags |= DBUS_WATCH_READABLE;
- if (FD_ISSET(fd, wset))
+ if (poll_check(fd, POLLOUT))
flags |= DBUS_WATCH_WRITABLE;
- if (FD_ISSET(fd, eset))
+ if (poll_check(fd, POLLERR))
flags |= DBUS_WATCH_ERROR;
if (flags != 0)
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 @@ struct daemon *daemon;
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 @@ int main (int argc, char **argv)
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 @@ int main (int argc, char **argv)
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 @@ int main (int argc, char **argv)
# 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 @@ int main (int argc, char **argv)
/* 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 (do_poll(timeout) < 0)
+ continue;
- if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
- {
- /* otherwise undefined after error */
- FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
- }
-
now = dnsmasq_time();
- check_log_writer(&wset);
+ check_log_writer(0);
/* prime. */
enumerate_interfaces(1);
@@ -978,15 +957,15 @@ int main (int argc, char **argv)
}
#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 @@ int main (int argc, char **argv)
}
#endif
- if (FD_ISSET(piperead, &rset))
+ if (poll_check(piperead, POLLIN))
async_event(piperead, now);
#ifdef HAVE_DBUS
@@ -1019,34 +998,34 @@ int main (int argc, char **argv)
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 @@ void clear_cache_and_reload(time_t now)
#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 @@ static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
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 @@ static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
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 @@ static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
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 @@ static int set_dns_listeners(time_t now, fd_set *set, int *maxfdp)
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 @@ int icmp_ping(struct in_addr addr)
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 &&
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 2be27f1..de146c6 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -82,7 +82,7 @@ typedef unsigned long long u64;
#if defined(HAVE_SOLARIS_NETWORK)
# include <sys/sockio.h>
#endif
-#include <sys/select.h>
+#include <sys/poll.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/un.h>
@@ -1191,7 +1191,6 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len,
unsigned int mask);
int expand_buf(struct iovec *iov, size_t size);
char *print_mac(char *buff, unsigned char *mac, int len);
-void bump_maxfd(fd_set *set, int fd, int *max);
int read_write(int fd, unsigned char *packet, int size, int rw);
int wildcard_match(const char* wildcard, const char* match);
@@ -1202,8 +1201,8 @@ void die(char *message, char *arg1, int exit_code);
int log_start(struct passwd *ent_pw, int errfd);
int log_reopen(char *log_file);
void my_syslog(int priority, const char *format, ...);
-void set_log_writer(fd_set *set, int *maxfdp);
-void check_log_writer(fd_set *set);
+void set_log_writer(void);
+void check_log_writer(int force);
void flush_log(void);
/* option.c */
@@ -1366,8 +1365,8 @@ int iface_enumerate(int family, void *parm, int (callback)());
/* dbus.c */
#ifdef HAVE_DBUS
char *dbus_init(void);
-void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset);
-void set_dbus_listeners(int *maxfdp, fd_set *rset, fd_set *wset, fd_set *eset);
+void check_dbus_listeners(void);
+void set_dbus_listeners(void);
# ifdef HAVE_DHCP
void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
# endif
@@ -1394,7 +1393,7 @@ int helper_buf_empty(void);
/* tftp.c */
#ifdef HAVE_TFTP
void tftp_request(struct listener *listen, time_t now);
-void check_tftp_listeners(fd_set *rset, time_t now);
+void check_tftp_listeners(time_t now);
int do_tftp_script_run(void);
#endif
@@ -1511,3 +1510,10 @@ void inotify_dnsmasq_init();
int inotify_check(time_t now);
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
#endif
+
+/* poll.c */
+void poll_reset(void);
+int poll_check(int fd, short event);
+void poll_listen(int fd, short event);
+int do_poll(int timeout);
+
diff --git a/src/forward.c b/src/forward.c
index b40dda3..de00ca0 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -1887,7 +1887,7 @@ unsigned char *tcp_request(int confd, time_t now,
dst_addr_4, netmask, now, &ad_question, &do_bit);
/* Do this by steam now we're not in the select() loop */
- check_log_writer(NULL);
+ check_log_writer(1);
if (m == 0)
{
@@ -2108,7 +2108,7 @@ unsigned char *tcp_request(int confd, time_t now,
}
}
- check_log_writer(NULL);
+ check_log_writer(1);
*length = htons(m);
diff --git a/src/log.c b/src/log.c
index 8e2f930..27b2e59 100644
--- a/src/log.c
+++ b/src/log.c
@@ -421,15 +421,15 @@ void my_syslog(int priority, const char *format, ...)
}
}
-void set_log_writer(fd_set *set, int *maxfdp)
+void set_log_writer(void)
{
if (entries && log_fd != -1 && connection_good)
- bump_maxfd(set, log_fd, maxfdp);
+ poll_listen(log_fd, POLLOUT);
}
-void check_log_writer(fd_set *set)
+void check_log_writer(int force)
{
- if (log_fd != -1 && (!set || FD_ISSET(log_fd, set)))
+ if (log_fd != -1 && (force || poll_check(log_fd, POLLOUT)))
log_write();
}
diff --git a/src/poll.c b/src/poll.c
new file mode 100644
index 0000000..01b3564
--- /dev/null
+++ b/src/poll.c
@@ -0,0 +1,124 @@
+/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 dated June, 1991, or
+ (at your option) version 3 dated 29 June, 2007.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+/* Wrapper for poll(). Allocates and extends array of struct pollfds,
+ keeps them in fd order so that we can set and test conditions on
+ fd using a simple but efficient binary chop. */
+
+/* poll_reset()
+ poll_listen(fd, event)
+ .
+ .
+ poll_listen(fd, event);
+
+ hits = do_poll(timeout);
+
+ if (poll_check(fd, event)
+ .
+ .
+
+ if (poll_check(fd, event)
+ .
+ .
+
+ event is OR of POLLIN, POLLOUT, POLLERR, etc
+*/
+
+static struct pollfd *pollfds = NULL;
+static nfds_t nfds, arrsize = 0;
+
+/* Binary search. Returns either the pollfd with fd, or
+ if the fd doesn't match, or return equals nfds, the entry
+ to the left of which a new record should be inserted. */
+static nfds_t fd_search(int fd)
+{
+ nfds_t left, right, mid;
+
+ if ((right = nfds) == 0)
+ return 0;
+
+ left = 0;
+
+ while (1)
+ {
+ if (right == left + 1)
+ return (pollfds[left].fd >= fd) ? left : right;
+
+ mid = (left + right)/2;
+
+ if (pollfds[mid].fd > fd)
+ right = mid;
+ else
+ left = mid;
+ }
+}
+
+void poll_reset(void)
+{
+ nfds = 0;
+}
+
+int do_poll(int timeout)
+{
+ return poll(pollfds, nfds, timeout);
+}
+
+int poll_check(int fd, short event)
+{
+ nfds_t i = fd_search(fd);
+
+ if (i < nfds && pollfds[i].fd == fd)
+ return pollfds[i].revents & event;
+
+ return 0;
+}
+
+void poll_listen(int fd, short event)
+{
+ nfds_t i = fd_search(fd);
+
+ if (i < nfds && pollfds[i].fd == fd)
+ pollfds[i].events |= event;
+ else
+ {
+ if (arrsize != nfds)
+ memmove(&pollfds[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
+ else
+ {
+ /* Array too small, extend. */
+ struct pollfd *new;
+ arrsize += 64;
+
+ if (!(new = whine_malloc(arrsize * sizeof(struct pollfd))))
+ return;
+
+ if (pollfds)
+ {
+ memcpy(new, pollfds, i * sizeof(struct pollfd));
+ memcpy(&new[i+1], &pollfds[i], (nfds - i) * sizeof(struct pollfd));
+ free(pollfds);
+ }
+
+ pollfds = new;
+ }
+
+ pollfds[i].fd = fd;
+ pollfds[i].events = event;
+ nfds++;
+ }
+}
diff --git a/src/tftp.c b/src/tftp.c
index d3fb6d7..350a587 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -502,7 +502,7 @@ static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix)
return NULL;
}
-void check_tftp_listeners(fd_set *rset, time_t now)
+void check_tftp_listeners(time_t now)
{
struct tftp_transfer *transfer, *tmp, **up;
ssize_t len;
@@ -518,7 +518,7 @@ void check_tftp_listeners(fd_set *rset, time_t now)
prettyprint_addr(&transfer->peer, daemon->addrbuff);
- if (FD_ISSET(transfer->sockfd, rset))
+ if (poll_check(transfer->sockfd, POLLIN))
{
/* we overwrote the buffer... */
daemon->srv_save = NULL;
diff --git a/src/util.c b/src/util.c
index 3b7fad8..469eaed 100644
--- a/src/util.c
+++ b/src/util.c
@@ -570,25 +570,6 @@ char *print_mac(char *buff, unsigned char *mac, int len)
return buff;
}
-void bump_maxfd(fd_set *set, int fd, int *max)
-{
-#ifdef FD_SETSIZE
- if (fd >= FD_SETSIZE)
- {
- static int logged = 0;
- if (!logged)
- my_syslog(LOG_ERR, _("File descriptor overflows FD_SET"));
- logged = 1;
- }
- else
- #endif
- {
- FD_SET(fd, set);
- if (fd > *max)
- *max = fd;
- }
-}
-
/* rc is return from sendto and friends.
Return 1 if we should retry.
Set errno to zero if we succeeded. */