From ad080a65a3e118c1b0f00e67a13c6f40b04446d3 Mon Sep 17 00:00:00 2001
From: djm <>
Date: Fri, 18 Apr 2008 21:36:32 +0000
Subject: convert select() => poll(), saves a runtime malloc+free per retry
 feedback deraadt@ drahn@; ok deraadt@

---
 src/lib/libc/net/res_send.c | 39 ++++++++++++++++-----------------------
 1 file changed, 16 insertions(+), 23 deletions(-)

(limited to 'src')

diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c
index f7631350bc..187210cbd8 100644
--- a/src/lib/libc/net/res_send.c
+++ b/src/lib/libc/net/res_send.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: res_send.c,v 1.19 2005/08/06 20:30:04 espie Exp $	*/
+/*	$OpenBSD: res_send.c,v 1.20 2008/04/18 21:36:32 djm Exp $	*/
 
 /*
  * ++Copyright++ 1985, 1989, 1993
@@ -75,10 +75,11 @@
 #include <arpa/nameser.h>
 #include <arpa/inet.h>
 
-#include <stdio.h>
-#include <netdb.h>
 #include <errno.h>
+#include <netdb.h>
+#include <poll.h>
 #include <resolv.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -466,7 +467,7 @@ res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
 			/*
 			 * Receive length & response
 			 */
-read_len:
+ read_len:
 			cp = ans;
 			len = INT16SZ;
 			while ((n = read(s, (char *)cp, (int)len)) > 0) {
@@ -553,8 +554,8 @@ read_len:
 			/*
 			 * Use datagrams.
 			 */
-			struct timeval timeout;
-			fd_set *dsmaskp;
+			struct pollfd pfd;
+			int timeout;
 			struct sockaddr_storage from;
 			socklen_t fromlen;
 
@@ -594,7 +595,7 @@ read_len:
 			 * ICMP port unreachable message to be returned.
 			 * If our datagram socket is "connected" to the
 			 * server, we get an ECONNREFUSED error on the next
-			 * socket operation, and select returns if the
+			 * socket operation, and poll returns if the
 			 * error message is received.  We can thus detect
 			 * the absence of a nameserver without timing out.
 			 * If we have sent queries to at least two servers,
@@ -676,27 +677,19 @@ read_len:
 			/*
 			 * Wait for reply
 			 */
-			timeout.tv_sec = (_resp->retrans << try);
+			timeout = 1000 * (_resp->retrans << try);
 			if (try > 0)
-				timeout.tv_sec /= _resp->nscount;
-			if ((long) timeout.tv_sec <= 0)
-				timeout.tv_sec = 1;
-			timeout.tv_usec = 0;
+				timeout /= _resp->nscount;
+			if (timeout < 1000)
+				timeout = 1000;
     wait:
-			dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS),
-						   sizeof(fd_mask));
-			if (dsmaskp == NULL) {
-				res_close();
-				goto next_ns;
-			}
-			FD_SET(s, dsmaskp);
-			n = select(s+1, dsmaskp, (fd_set *)NULL,
-				   (fd_set *)NULL, &timeout);
-			free(dsmaskp);
+			pfd.fd = s;
+			pfd.events = POLLIN;
+			n = poll(&pfd, 1, timeout);
 			if (n < 0) {
 				if (errno == EINTR)
 					goto wait;
-				Perror(stderr, "select", errno);
+				Perror(stderr, "poll", errno);
 				res_close();
 				goto next_ns;
 			}
-- 
cgit v1.2.3-55-g6feb