svn commit: trunk/uClibc/libc/inet

pkj at uclibc.org pkj at uclibc.org
Fri Jan 11 09:03:27 UTC 2008


Author: pkj
Date: 2008-01-11 01:03:27 -0800 (Fri, 11 Jan 2008)
New Revision: 20842

Log:
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.


Modified:
   trunk/uClibc/libc/inet/resolv.c


Changeset:
Modified: trunk/uClibc/libc/inet/resolv.c
===================================================================
--- trunk/uClibc/libc/inet/resolv.c	2008-01-10 09:31:56 UTC (rev 20841)
+++ trunk/uClibc/libc/inet/resolv.c	2008-01-11 09:03:27 UTC (rev 20842)
@@ -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,7 +877,18 @@
 			 * 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) {
 			/* too short ! */




More information about the uClibc-cvs mailing list