libs: s3 and s4: make our dns lookup code signal-safe.
authorJeremy Allison <jra@samba.org>
Wed, 9 Apr 2014 22:27:45 +0000 (15:27 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 10 Apr 2014 20:06:08 +0000 (22:06 +0200)
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

lib/addns/dnssock.c

index 5f9951913587f2edb83aa51de00d50ed11925b87..13649b5dd4c63dafe68bee64f304bf8311b6ab06 100644 (file)
@@ -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 );
 
        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;
        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) {
 
 
        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) {
                        /*
 
                if (ret <= 0) {
                        /*
@@ -187,9 +193,11 @@ static DNS_ERROR dns_send_udp(struct dns_connection *conn,
 {
        ssize_t ret;
 
 {
        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));
                     (struct sockaddr *)&conn->RecvAddr,
                     sizeof(conn->RecvAddr));
+       } while ((ret == -1) && (errno == EINTR));
 
        if (ret != buf->offset) {
                return ERROR_DNS_SOCKET_ERROR;
 
        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);
                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;
                }
 
                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;
                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;
        }
 
                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);
 
        if (received == -1) {
                TALLOC_FREE(buf);