diff options
| author | Paul Saab <ps@FreeBSD.org> | 2000-09-20 21:37:01 +0000 |
|---|---|---|
| committer | Paul Saab <ps@FreeBSD.org> | 2000-09-20 21:37:01 +0000 |
| commit | 329cf91ab0868f6748fe47629ca67f837587a5a9 (patch) | |
| tree | 2c4a39acca1b1c08c50580850832728c8f4bc476 /lib/libc | |
| parent | 880c9e41fb339c310098e80159c6a13841a22e59 (diff) | |
Notes
Diffstat (limited to 'lib/libc')
| -rw-r--r-- | lib/libc/net/res_send.c | 146 |
1 files changed, 33 insertions, 113 deletions
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c index da196fba52bb..e720fc7bc234 100644 --- a/lib/libc/net/res_send.c +++ b/lib/libc/net/res_send.c @@ -79,6 +79,7 @@ static char rcsid[] = "$FreeBSD$"; */ #include <sys/types.h> +#include <sys/event.h> #include <sys/param.h> #include <sys/time.h> #include <sys/socket.h> @@ -95,17 +96,9 @@ static char rcsid[] = "$FreeBSD$"; #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <poll.h> #include "res_config.h" -#ifdef NOPOLL /* libc_r doesn't wrap poll yet() */ -static int use_poll = 0; -#else -static int use_poll = 1; /* adapt to poll() syscall availability */ - /* 0 = not present, 1 = try it, 2 = exists */ -#endif - static int s = -1; /* socket used for communications */ static int connected = 0; /* is the socket connected */ static int vc = 0; /* is the socket a virtual circuit? */ @@ -363,6 +356,7 @@ res_send(buf, buflen, ans, anssiz) HEADER *hp = (HEADER *) buf; HEADER *anhp = (HEADER *) ans; int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n; + int kq; u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */ if ((_res.options & RES_INIT) == 0 && res_init() == -1) { @@ -381,6 +375,11 @@ res_send(buf, buflen, ans, anssiz) terrno = ETIMEDOUT; badns = 0; + if ((kq = kqueue()) < 0) { + Perror(stderr, "kqueue", errno); + return (-1); + } + /* * Send request, RETRY times, or until successful */ @@ -421,6 +420,7 @@ res_send(buf, buflen, ans, anssiz) res_close(); goto next_ns; case res_done: + close(kq); return (resplen); case res_modified: /* give the hook another try */ @@ -430,6 +430,7 @@ res_send(buf, buflen, ans, anssiz) case res_error: /*FALLTHROUGH*/ default: + close(kq); return (-1); } } while (!done); @@ -594,13 +595,8 @@ read_len: /* * Use datagrams. */ -#ifndef NOPOLL - struct pollfd pfd; - int msec; -#endif - struct timeval timeout; - fd_set dsmask, *dsmaskp; - int dsmasklen; + struct kevent kv; + struct timespec timeout; struct sockaddr_storage from; int fromlen; @@ -703,111 +699,32 @@ read_len: /* * Wait for reply */ -#ifndef NOPOLL - othersyscall: - if (use_poll) { - struct timeval itv; - - msec = (_res.retrans << try) * 1000; - if (try > 0) - msec /= _res.nscount; - if (msec <= 0) - msec = 1000; - gettimeofday(&timeout, NULL); - itv.tv_sec = msec / 1000; - itv.tv_usec = (msec % 1000) * 1000; - timeradd(&timeout, &itv, &timeout); - } else { -#endif - timeout.tv_sec = (_res.retrans << try); - if (try > 0) - timeout.tv_sec /= _res.nscount; - if ((long) timeout.tv_sec <= 0) - timeout.tv_sec = 1; - timeout.tv_usec = 0; -#ifndef NOPOLL - } -#endif + + timeout.tv_sec = (_res.retrans << try); + if (try > 0) + timeout.tv_sec /= _res.nscount; + if ((long) timeout.tv_sec <= 0) + timeout.tv_sec = 1; + timeout.tv_nsec = 0; wait: if (s < 0) { Perror(stderr, "s out-of-bounds", EMFILE); res_close(); goto next_ns; } -#ifndef NOPOLL - if (use_poll) { - struct sigaction sa, osa; - int sigsys_installed = 0; - - pfd.fd = s; - pfd.events = POLLIN; - if (use_poll == 1) { - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - if (sigaction(SIGSYS, &sa, &osa) >= 0) - sigsys_installed = 1; - } - n = poll(&pfd, 1, msec); - if (sigsys_installed == 1) { - int oerrno = errno; - sigaction(SIGSYS, &osa, NULL); - errno = oerrno; - } - /* XXX why does nosys() return EINVAL? */ - if (n < 0 && (errno == ENOSYS || - errno == EINVAL)) { - use_poll = 0; - goto othersyscall; - } else if (use_poll == 1) - use_poll = 2; - if (n < 0) { - if (errno == EINTR) { - struct timeval ctv; - - gettimeofday(&ctv, NULL); - if (timercmp(&ctv, &timeout, <)) { - timersub(&timeout, - &ctv, &ctv); - msec = ctv.tv_sec * 1000; - msec += ctv.tv_usec / 1000; - goto wait; - } - } else { - Perror(stderr, "poll", errno); - res_close(); - goto next_ns; - } - } - } else { -#endif - dsmasklen = howmany(s + 1, NFDBITS) * - sizeof(fd_mask); - if (dsmasklen > sizeof(fd_set)) { - dsmaskp = (fd_set *)malloc(dsmasklen); - if (dsmaskp == NULL) { - res_close(); - goto next_ns; - } - } else - dsmaskp = &dsmask; - /* only zero what we need */ - bzero((char *)dsmaskp, dsmasklen); - FD_SET(s, dsmaskp); - n = select(s + 1, dsmaskp, (fd_set *)NULL, - (fd_set *)NULL, &timeout); - if (dsmaskp != &dsmask) - free(dsmaskp); - if (n < 0) { - if (errno == EINTR) - goto wait; - Perror(stderr, "select", errno); - res_close(); - goto next_ns; - } -#ifndef NOPOLL + + kv.ident = s; + kv.flags = EV_ADD | EV_ONESHOT; + kv.filter = EVFILT_READ; + + n = kevent(kq, &kv, 1, &kv, 1, &timeout); + if (n < 0) { + if (errno == EINTR) + goto wait; + Perror(stderr, "kevent", errno); + res_close(); + goto next_ns; } -#endif if (n == 0) { /* @@ -951,16 +868,19 @@ read_len: case res_error: /*FALLTHROUGH*/ default: + close(kq); return (-1); } } while (!done); } + close(kq); return (resplen); next_ns: ; } /*foreach ns*/ } /*foreach retry*/ res_close(); + close(kq); if (!v_circuit) { if (!gotsomewhere) errno = ECONNREFUSED; /* no nameservers found */ |
