[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