From e4f07e7d1b9c6b2eab58fdebd3b9031f361d59aa Mon Sep 17 00:00:00 2001 From: Peter Kjellerstedt Date: Fri, 11 Jan 2008 09:03:27 +0000 Subject: Use poll() rather than select() if the former is available to wait in __dns_lookup(). This avoids segmentation faults when more than 1024 file descriptors are used by an application. --- libc/inet/resolv.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 591106a24..5df8fecaa 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -140,6 +140,7 @@ #include #include #include +#include #include #include #include @@ -157,6 +158,14 @@ #include #include +/* poll() is not supported in kernel <= 2.0, therefore if __NR_poll is + * not available, we assume an old Linux kernel is in use and we will + * use select() instead. */ +#include +#ifndef __NR_poll +# define USE_SELECT +#endif + __UCLIBC_MUTEX_EXTERN(__resolv_lock); libc_hidden_proto(memcpy) @@ -185,6 +194,7 @@ libc_hidden_proto(inet_aton) libc_hidden_proto(inet_pton) libc_hidden_proto(inet_ntop) libc_hidden_proto(connect) +libc_hidden_proto(poll) libc_hidden_proto(select) libc_hidden_proto(recv) libc_hidden_proto(send) @@ -721,8 +731,12 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char unsigned char **outpacket, struct resolv_answer *a) { int i, j, len, fd, pos, rc; +#ifdef USE_SELECT struct timeval tv; fd_set fds; +#else + struct pollfd fds; +#endif struct resolv_header h; struct resolv_question q; struct resolv_answer ma; @@ -851,6 +865,7 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char send(fd, packet, len, 0); +#ifdef USE_SELECT FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = REPLY_TIMEOUT; @@ -862,6 +877,17 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char * to next nameserver on queue */ goto tryall; } +#else + fds.fd = fd; + fds.events = POLLIN; + if (poll(&fds, 1, REPLY_TIMEOUT * 1000) <= 0) { + DPRINTF("Timeout\n"); + + /* timed out, so retry send and receive, + * to next nameserver on queue */ + goto tryall; + } +#endif len = recv(fd, packet, 512, 0); if (len < HFIXEDSZ) { -- cgit v1.2.3