summaryrefslogtreecommitdiff
path: root/lib/addns
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-04-09 15:27:45 -0700
committerJeremy Allison <jra@samba.org>2014-04-10 22:06:08 +0200
commit4daf7d475c8cca69e2e3b20dc9fb84c4bd8cb4cb (patch)
treea85336ff697d360ea4acf8e2ed03a91f543a8b13 /lib/addns
parentf5a3d74264abb25009e73b1b35d62db34fa62343 (diff)
downloadsamba-4daf7d475c8cca69e2e3b20dc9fb84c4bd8cb4cb.tar.gz
libs: s3 and s4: make our dns lookup code signal-safe.
Cope with -1,EINTR returns. Needed as this code can be called from inside smbd. Also fixes a bug in not checking the return from poll() correctly. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Kai Blin <kai@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Thu Apr 10 22:06:08 CEST 2014 on sn-devel-104
Diffstat (limited to 'lib/addns')
-rw-r--r--lib/addns/dnssock.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/lib/addns/dnssock.c b/lib/addns/dnssock.c
index 5f995191358..13649b5dd4c 100644
--- a/lib/addns/dnssock.c
+++ b/lib/addns/dnssock.c
@@ -70,7 +70,9 @@ static DNS_ERROR dns_tcp_open( const char *nameserver,
s_in.sin_addr.s_addr = ulAddress;
s_in.sin_port = htons( DNS_TCP_PORT );
- res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in ));
+ do {
+ res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in ));
+ } while ((res == -1) && (errno == EINTR));
if (res == -1) {
TALLOC_FREE(conn);
return ERROR_DNS_CONNECTION_FAILED;
@@ -155,7 +157,11 @@ static DNS_ERROR write_all(int fd, uint8_t *data, size_t len)
while (total < len) {
- ssize_t ret = write(fd, data + total, len - total);
+ ssize_t ret;
+
+ do {
+ ret = write(fd, data + total, len - total);
+ } while ((ret == -1) && (errno == EINTR));
if (ret <= 0) {
/*
@@ -187,9 +193,11 @@ static DNS_ERROR dns_send_udp(struct dns_connection *conn,
{
ssize_t ret;
- ret = sendto(conn->s, buf->data, buf->offset, 0,
+ do {
+ ret = sendto(conn->s, buf->data, buf->offset, 0,
(struct sockaddr *)&conn->RecvAddr,
sizeof(conn->RecvAddr));
+ } while ((ret == -1) && (errno == EINTR));
if (ret != buf->offset) {
return ERROR_DNS_SOCKET_ERROR;
@@ -225,12 +233,21 @@ static DNS_ERROR read_all(int fd, uint8_t *data, size_t len)
pfd.events = POLLIN|POLLHUP;
fd_ready = poll(&pfd, 1, 10000);
+ if (fd_ready == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+ return ERROR_DNS_SOCKET_ERROR;
+ }
if ( fd_ready == 0 ) {
/* read timeout */
return ERROR_DNS_SOCKET_ERROR;
}
- ret = read(fd, data + total, len - total);
+ do {
+ ret = read(fd, data + total, len - total);
+ } while ((ret == -1) && (errno == EINTR));
+
if (ret <= 0) {
/* EOF or error */
return ERROR_DNS_SOCKET_ERROR;
@@ -300,7 +317,9 @@ static DNS_ERROR dns_receive_udp(TALLOC_CTX *mem_ctx,
return ERROR_DNS_NO_MEMORY;
}
- received = recv(conn->s, (void *)buf->data, 512, 0);
+ do {
+ received = recv(conn->s, (void *)buf->data, 512, 0);
+ } while ((received == -1) && (errno == EINTR));
if (received == -1) {
TALLOC_FREE(buf);