[PATCH] Make libc/inet/resolv.c use poll() rather than select()
Peter Kjellerstedt
peter.kjellerstedt at axis.com
Thu Jan 10 16:51:17 UTC 2008
I intend to apply the patch below unless anyone has any objections.
The reason is that if one has used setrlimit(RLIMIT_NOFILE, x) with
x > 1024, using the FD_ macros will cause memory corruptions if a
file descriptor >= 1024 happens to be used since the macros are
limited to FD_SETSIZE (which is 1024).
This is basically the same solution as is already used in
libpthread/linuxthreads.old/manager.c (the only other place in the
uClibc code where select() is used).
Index: uClibc/libc/inet/resolv.c
===================================================================
--- uClibc/libc/inet/resolv.c (revision 20841)
+++ uClibc/libc/inet/resolv.c (working copy)
@@ -140,6 +140,7 @@
#include <stdio.h>
#include <signal.h>
#include <errno.h>
+#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
@@ -157,6 +158,14 @@
#include <sys/un.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);
libc_hidden_proto(memcpy)
@@ -185,6 +194,7 @@
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 @@
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 @@
send(fd, packet, len, 0);
+#ifdef USE_SELECT
FD_ZERO(&fds);
FD_SET(fd, &fds);
tv.tv_sec = REPLY_TIMEOUT;
@@ -862,6 +877,17 @@
* 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) {
//Peter
More information about the uClibc
mailing list