#include <time.h>
#include <ctype.h>
#include <unistd.h>
+#include <pthread.h>
#include "__dns.h"
#include "stdio_impl.h"
struct sockaddr_in6 sin6;
} sa = {0}, ns[3] = {{0}};
socklen_t sl;
- int nns;
- int family;
+ int nns = 0;
+ int family = AF_UNSPEC;
unsigned char q[280] = "", *r = dest;
int ql;
int rlen;
struct timeval tv;
fd_set fds;
int id;
+ int cs;
/* Construct query template - RR and ID will be filled later */
- if (strlen(name)-1 >= 254U) return -1;
+ if (strlen(name)-1 >= 254U) return EAI_NONAME;
q[2] = q[5] = 1;
- strcpy(q+13, name);
+ strcpy((char *)q+13, name);
for (i=13; q[i]; i=j+1) {
for (j=i; q[j] && q[j] != '.'; j++);
- if (j-i-1u > 62u) return -1;
+ if (j-i-1u > 62u) return EAI_NONAME;
q[i-1] = j-i;
}
q[i+3] = 1;
sl = sizeof sa.sin;
}
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
/* Get local address and open/bind a socket */
sa.sin.sin_family = family;
fd = socket(family, SOCK_DGRAM, 0);
if (bind(fd, (void *)&sa, sl) < 0) {
- close(fd);
- return -1;
+ errcode = EAI_SYSTEM;
+ goto out;
}
/* Nonblocking to work around Linux UDP select bug */
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
/* Check to see if we have answers to all queries */
if (got+failed == rrcnt) break;
}
+out:
close(fd);
+ pthread_setcancelstate(cs, 0);
/* Return the number of results, or an error code if none */
if (got) return got;
int found=0, res, i;
static const int p[2][2] = { { 4, RR_A }, { 16, RR_AAAA } };
- while (cnt--) for (i=0; i<2; i++) {
- res = __dns_get_rr(0, 0, p[i][0], -1, r, p[i][1], 0);
- if (res < 0) return res;
- found += res;
+ while (cnt--) {
+ for (i=0; i<2; i++) {
+ res = __dns_get_rr(0, 0, p[i][0], -1, r, p[i][1], 0);
+ if (res < 0) return res;
+ found += res;
+ }
r += 512;
}
return found;