|
@@ -140,6 +140,7 @@
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <signal.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <errno.h>
|
|
|
|
+#include <sys/poll.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/time.h>
|
|
@@ -157,6 +158,14 @@
|
|
#include <sys/un.h>
|
|
#include <sys/un.h>
|
|
#include <bits/uClibc_mutex.h>
|
|
#include <bits/uClibc_mutex.h>
|
|
|
|
|
|
|
|
+/* 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 <sys/syscall.h>
|
|
|
|
+#ifndef __NR_poll
|
|
|
|
+# define USE_SELECT
|
|
|
|
+#endif
|
|
|
|
+
|
|
__UCLIBC_MUTEX_EXTERN(__resolv_lock);
|
|
__UCLIBC_MUTEX_EXTERN(__resolv_lock);
|
|
|
|
|
|
libc_hidden_proto(memcpy)
|
|
libc_hidden_proto(memcpy)
|
|
@@ -185,6 +194,7 @@ libc_hidden_proto(inet_aton)
|
|
libc_hidden_proto(inet_pton)
|
|
libc_hidden_proto(inet_pton)
|
|
libc_hidden_proto(inet_ntop)
|
|
libc_hidden_proto(inet_ntop)
|
|
libc_hidden_proto(connect)
|
|
libc_hidden_proto(connect)
|
|
|
|
+libc_hidden_proto(poll)
|
|
libc_hidden_proto(select)
|
|
libc_hidden_proto(select)
|
|
libc_hidden_proto(recv)
|
|
libc_hidden_proto(recv)
|
|
libc_hidden_proto(send)
|
|
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)
|
|
unsigned char **outpacket, struct resolv_answer *a)
|
|
{
|
|
{
|
|
int i, j, len, fd, pos, rc;
|
|
int i, j, len, fd, pos, rc;
|
|
|
|
+#ifdef USE_SELECT
|
|
struct timeval tv;
|
|
struct timeval tv;
|
|
fd_set fds;
|
|
fd_set fds;
|
|
|
|
+#else
|
|
|
|
+ struct pollfd fds;
|
|
|
|
+#endif
|
|
struct resolv_header h;
|
|
struct resolv_header h;
|
|
struct resolv_question q;
|
|
struct resolv_question q;
|
|
struct resolv_answer ma;
|
|
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);
|
|
send(fd, packet, len, 0);
|
|
|
|
|
|
|
|
+#ifdef USE_SELECT
|
|
FD_ZERO(&fds);
|
|
FD_ZERO(&fds);
|
|
FD_SET(fd, &fds);
|
|
FD_SET(fd, &fds);
|
|
tv.tv_sec = REPLY_TIMEOUT;
|
|
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 */
|
|
* to next nameserver on queue */
|
|
goto tryall;
|
|
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);
|
|
len = recv(fd, packet, 512, 0);
|
|
if (len < HFIXEDSZ) {
|
|
if (len < HFIXEDSZ) {
|