summaryrefslogtreecommitdiff
path: root/resolv
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-10-12 12:00:26 +0000
committerJakub Jelinek <jakub@redhat.com>2004-10-12 12:00:26 +0000
commit3ee87ca7d4c813087eeee8b9fd04b7836244a54a (patch)
tree30d5d50dce77cb2e80d0bead19ee23e7d0a38617 /resolv
parent7dbf6a6cd568437c4b2fa14bcf5a1914cc267527 (diff)
downloadglibc-3ee87ca7d4c813087eeee8b9fd04b7836244a54a.tar.gz
Updated to fedora-glibc-20041012T1128cvs/fedora-glibc-2_3_3-67
Diffstat (limited to 'resolv')
-rw-r--r--resolv/res_init.c3
-rw-r--r--resolv/res_mkquery.c2
-rw-r--r--resolv/res_send.c106
3 files changed, 87 insertions, 24 deletions
diff --git a/resolv/res_init.c b/resolv/res_init.c
index 4087597a87..731c784e17 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -597,6 +597,9 @@ res_thread_freeres (void)
free (_res._u._ext.nsaddrs[ns]);
_res._u._ext.nsaddrs[ns] = NULL;
}
+
+ /* Make sure we do a full re-initialization the next time. */
+ _res.options = 0;
}
text_set_element (__libc_thread_subfreeres, res_thread_freeres);
text_set_element (__libc_subfreeres, res_thread_freeres);
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 5b705b0e8b..9825ae0fa3 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -141,7 +141,7 @@ res_nmkquery(res_state statp,
randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
#endif
}
- while (randombits == 0);
+ while ((randombits & 0xffff) == 0);
statp->id = (statp->id + randombits) & 0xffff;
#endif
hp->opcode = op;
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 2366f59cd2..44d8cb0fee 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -88,6 +88,7 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi
#include <sys/ioctl.h>
#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
#include <resolv.h>
#include <signal.h>
@@ -965,12 +966,73 @@ send_dg(res_state statp,
return (0);
}
#endif /* !CANNOT_CONNECT_DGRAM */
+ /* Make socket non-blocking. */
+ int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL);
+ if (fl != -1)
+ __fcntl (EXT(statp).nssocks[ns], F_SETFL,
+ fl | O_NONBLOCK);
Dprint(statp->options & RES_DEBUG,
(stdout, ";; new DG socket\n"))
}
s = EXT(statp).nssocks[ns];
+ /*
+ * Compute time for the total operation.
+ */
+ seconds = (statp->retrans << ns);
+ if (ns > 0)
+ seconds /= statp->nscount;
+ if (seconds <= 0)
+ seconds = 1;
+ evNowTime(&now);
+ evConsTime(&timeout, seconds, 0);
+ evAddTime(&finish, &now, &timeout);
+ int need_recompute = 0;
+ resend:
+#ifdef _LIBC
+ /* Convert struct timespec in milliseconds. */
+ ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
+
+ pfd[0].fd = s;
+ pfd[0].events = POLLOUT;
+ n = __poll (pfd, 1, 0);
+ if (__builtin_expect (n == 0, 0)) {
+ n = __poll (pfd, 1, ptimeout);
+ need_recompute = 1;
+ }
+#else
+ FD_ZERO(&dsmask);
+ FD_SET(s, &dsmask);
+ struct timeval zerotime = { 0, 0 };
+ n = pselect(s + 1, NULL, &dsmask, NULL, &zerotime, NULL);
+ if (n == 0) {
+ n = pselect(s + 1, NULL, &dsmask, NULL, &timeout, NULL);
+ need_recompute = 1;
+ }
+#endif
+ if (n == 0) {
+ Dprint(statp->options & RES_DEBUG, (stdout,
+ ";; timeout sending\n"));
+ *gotsomewhere = 1;
+ return (0);
+ }
+ if (n < 0) {
+ if (errno == EINTR) {
+ recompute_resend:
+ evNowTime(&now);
+ if (evCmpTime(finish, now) > 0) {
+ evSubTime(&timeout, &finish, &now);
+ goto resend;
+ }
+ }
+ Perror(statp, stderr, "select", errno);
+ res_nclose(statp);
+ return (0);
+ }
+ __set_errno (0);
#ifndef CANNOT_CONNECT_DGRAM
if (send(s, (char*)buf, buflen, 0) != buflen) {
+ if (errno == EINTR || errno == EAGAIN)
+ goto recompute_resend;
Perror(statp, stderr, "send", errno);
res_nclose(statp);
return (0);
@@ -984,6 +1046,8 @@ send_dg(res_state statp,
if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap, sizeof *nsap) != buflen)
{
+ if (errno == EINTR || errno == EAGAIN)
+ goto recompute_resend;
Aerror(statp, stderr, "sendto", errno,
(struct sockaddr *) nsap);
res_nclose(statp);
@@ -991,46 +1055,38 @@ send_dg(res_state statp,
}
#endif /* !CANNOT_CONNECT_DGRAM */
- /*
- * Wait for reply.
- */
- seconds = (statp->retrans << ns);
- if (ns > 0)
- seconds /= statp->nscount;
- if (seconds <= 0)
- seconds = 1;
- evNowTime(&now);
- evConsTime(&timeout, seconds, 0);
- evAddTime(&finish, &now, &timeout);
wait:
+ if (need_recompute) {
+ evNowTime(&now);
+ if (evCmpTime(finish, now) <= 0) {
+ err_return:
+ Perror(statp, stderr, "select", errno);
+ res_nclose(statp);
+ return (0);
+ }
+ evSubTime(&timeout, &finish, &now);
+ }
#ifdef _LIBC
/* Convert struct timespec in milliseconds. */
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
- pfd[0].fd = s;
pfd[0].events = POLLIN;
n = __poll (pfd, 1, ptimeout);
#else
- FD_ZERO(&dsmask);
- FD_SET(s, &dsmask);
n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
#endif
if (n == 0) {
- Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
+ Dprint(statp->options & RES_DEBUG, (stdout,
+ ";; timeout receiving\n"));
*gotsomewhere = 1;
return (0);
}
if (n < 0) {
if (errno == EINTR) {
- evNowTime(&now);
- if (evCmpTime(finish, now) > 0) {
- evSubTime(&timeout, &finish, &now);
- goto wait;
- }
+ need_recompute = 1;
+ goto wait;
}
- Perror(statp, stderr, "select", errno);
- res_nclose(statp);
- return (0);
+ goto err_return;
}
__set_errno (0);
#ifdef _LIBC
@@ -1056,6 +1112,10 @@ send_dg(res_state statp,
resplen = recvfrom(s, (char*)ans, anssiz,0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
+ if (errno == EINTR || errno == EAGAIN) {
+ need_recompute = 1;
+ goto wait;
+ }
Perror(statp, stderr, "recvfrom", errno);
res_nclose(statp);
return (0);