diff options
author | Jeremy Allison <jra@samba.org> | 2014-04-09 15:27:45 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-04-10 22:06:08 +0200 |
commit | 4daf7d475c8cca69e2e3b20dc9fb84c4bd8cb4cb (patch) | |
tree | a85336ff697d360ea4acf8e2ed03a91f543a8b13 /lib/addns | |
parent | f5a3d74264abb25009e73b1b35d62db34fa62343 (diff) | |
download | samba-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.c | 29 |
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); |