diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-10-14 20:56:52 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-10-14 20:56:52 +0000 |
commit | a33c43a5aefbbb2d1e00432ba034d256af0008ae (patch) | |
tree | 80aa9060de68814fb13960b308a0faa95fb8ba94 /nscd | |
parent | 4cee966cabbbd52c38260dff95f5ab43772ba5d9 (diff) | |
download | glibc-a33c43a5aefbbb2d1e00432ba034d256af0008ae.tar glibc-a33c43a5aefbbb2d1e00432ba034d256af0008ae.tar.gz glibc-a33c43a5aefbbb2d1e00432ba034d256af0008ae.tar.bz2 glibc-a33c43a5aefbbb2d1e00432ba034d256af0008ae.zip |
Updated to fedora-glibc-20071014T1847
Diffstat (limited to 'nscd')
-rw-r--r-- | nscd/nscd_getai.c | 4 | ||||
-rw-r--r-- | nscd/nscd_getgr_r.c | 76 | ||||
-rw-r--r-- | nscd/nscd_gethst_r.c | 4 | ||||
-rw-r--r-- | nscd/nscd_getpw_r.c | 4 | ||||
-rw-r--r-- | nscd/nscd_getserv_r.c | 4 | ||||
-rw-r--r-- | nscd/nscd_helper.c | 103 |
6 files changed, 122 insertions, 73 deletions
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c index 5df32dc6dc..56f963776e 100644 --- a/nscd/nscd_getai.c +++ b/nscd/nscd_getai.c @@ -168,8 +168,8 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop) /* Store the error number. */ *h_errnop = ai_resp.error; - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c index fc036f2888..afb4d20435 100644 --- a/nscd/nscd_getgr_r.c +++ b/nscd/nscd_getgr_r.c @@ -190,26 +190,37 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, /* Read the length information, group name, and password. */ if (gr_name == NULL) { - /* Allocate array to store lengths. */ - if (lensize == 0) + /* Handle a simple, usual case: no group members. */ + if (__builtin_expect (gr_resp.gr_mem_cnt == 0, 1)) { - lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t); - len = (uint32_t *) alloca (lensize); + size_t n = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + if (__builtin_expect (__readall (sock, resultbuf->gr_name, n) + != (ssize_t) n, 0)) + goto out_close; + } + else + { + /* Allocate array to store lengths. */ + if (lensize == 0) + { + lensize = gr_resp.gr_mem_cnt * sizeof (uint32_t); + len = (uint32_t *) alloca (lensize); + } + else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize) + len = extend_alloca (len, lensize, + gr_resp.gr_mem_cnt * sizeof (uint32_t)); + + vec[0].iov_base = (void *) len; + vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t); + vec[1].iov_base = resultbuf->gr_name; + vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; + total_len = vec[0].iov_len + vec[1].iov_len; + + /* Get this data. */ + size_t n = __readvall (sock, vec, 2); + if (__builtin_expect (n != total_len, 0)) + goto out_close; } - else if (gr_resp.gr_mem_cnt * sizeof (uint32_t) > lensize) - len = extend_alloca (len, lensize, - gr_resp.gr_mem_cnt * sizeof (uint32_t)); - - vec[0].iov_base = (void *) len; - vec[0].iov_len = gr_resp.gr_mem_cnt * sizeof (uint32_t); - vec[1].iov_base = resultbuf->gr_name; - vec[1].iov_len = gr_resp.gr_name_len + gr_resp.gr_passwd_len; - total_len = vec[0].iov_len + vec[1].iov_len; - - /* Get this data. */ - size_t n = __readvall (sock, vec, 2); - if (__builtin_expect (n != total_len, 0)) - goto out_close; } else /* We already have the data. Just copy the group name and @@ -251,17 +262,22 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, } retval = 0; + + /* If there are no group members TOTAL_LEN is zero. */ if (gr_name == NULL) { - size_t n = __readall (sock, resultbuf->gr_mem[0], total_len); - if (__builtin_expect (n != total_len, 0)) + if (total_len > 0) { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); - retval = ENOENT; + size_t n = __readall (sock, resultbuf->gr_mem[0], total_len); + if (__builtin_expect (n != total_len, 0)) + { + /* The `errno' to some value != ERANGE. */ + __set_errno (ENOENT); + retval = ENOENT; + } + else + *result = resultbuf; } - else - *result = resultbuf; } else { @@ -272,9 +288,9 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, if (resultbuf->gr_name[gr_name_len - 1] != '\0' || resultbuf->gr_passwd[gr_resp.gr_passwd_len - 1] != '\0' || ({for (cnt = 0; cnt < gr_resp.gr_mem_cnt; ++cnt) - if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0') - break; - cnt < gr_resp.gr_mem_cnt; })) + if (resultbuf->gr_mem[cnt][len[cnt] - 1] != '\0') + break; + cnt < gr_resp.gr_mem_cnt; })) { /* We cannot use the database. */ retval = mapped->head->gc_cycle != gc_cycle ? -2 : -1; @@ -286,8 +302,8 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, } else { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c index 03b73a4a47..a211404756 100644 --- a/nscd/nscd_gethst_r.c +++ b/nscd/nscd_gethst_r.c @@ -379,8 +379,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type, /* Store the error number. */ *h_errnop = hst_resp.error; - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c index b84baa1a66..21f792bb4e 100644 --- a/nscd/nscd_getpw_r.c +++ b/nscd/nscd_getpw_r.c @@ -211,8 +211,8 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type, } else { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c index a725b1d3de..3cd5a24298 100644 --- a/nscd/nscd_getserv_r.c +++ b/nscd/nscd_getserv_r.c @@ -301,8 +301,8 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto, } else { - /* The `errno' to some value != ERANGE. */ - __set_errno (ENOENT); + /* Set errno to 0 to indicate no error, just no found record. */ + __set_errno (0); /* Even though we have not found anything, the result is zero. */ retval = 0; } diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c index 6718d922f3..866535200f 100644 --- a/nscd/nscd_helper.c +++ b/nscd/nscd_helper.c @@ -38,6 +38,45 @@ #include "nscd-client.h" +/* Extra time we wait if the socket is still receiving data. This + value is in milliseconds. Note that the other side is nscd on the + local machine and it is already transmitting data. So the wait + time need not be long. */ +#define EXTRA_RECEIVE_TIME 200 + + +static int +wait_on_socket (int sock, long int usectmo) +{ + struct pollfd fds[1]; + fds[0].fd = sock; + fds[0].events = POLLIN | POLLERR | POLLHUP; + int n = __poll (fds, 1, usectmo); + if (n == -1 && __builtin_expect (errno == EINTR, 0)) + { + /* Handle the case where the poll() call is interrupted by a + signal. We cannot just use TEMP_FAILURE_RETRY since it might + lead to infinite loops. */ + struct timeval now; + (void) __gettimeofday (&now, NULL); + long int end = now.tv_sec * 1000 + usectmo + (now.tv_usec + 500) / 1000; + long int timeout = usectmo; + while (1) + { + n = __poll (fds, 1, timeout); + if (n != -1 || errno != EINTR) + break; + + /* Recompute the timeout time. */ + (void) __gettimeofday (&now, NULL); + timeout = end - (now.tv_sec * 1000 + (now.tv_usec + 500) / 1000); + } + } + + return n; +} + + ssize_t __readall (int fd, void *buf, size_t len) { @@ -45,9 +84,17 @@ __readall (int fd, void *buf, size_t len) ssize_t ret; do { + again: ret = TEMP_FAILURE_RETRY (__read (fd, buf, n)); if (ret <= 0) - break; + { + if (__builtin_expect (ret < 0 && errno == EAGAIN, 0) + /* The socket is still receiving data. Wait a bit more. */ + && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0) + goto again; + + break; + } buf = (char *) buf + ret; n -= ret; } @@ -61,7 +108,15 @@ __readvall (int fd, const struct iovec *iov, int iovcnt) { ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt)); if (ret <= 0) - return ret; + { + if (__builtin_expect (ret == 0 || errno != EAGAIN, 1)) + /* A genuine error or no data to read. */ + return ret; + + /* The data has not all yet been received. Do as if we have not + read anything yet. */ + ret = 0; + } size_t total = 0; for (int i = 0; i < iovcnt; ++i) @@ -83,9 +138,17 @@ __readvall (int fd, const struct iovec *iov, int iovcnt) } iovp->iov_base = (char *) iovp->iov_base + r; iovp->iov_len -= r; + again: r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt)); if (r <= 0) - break; + { + if (__builtin_expect (r < 0 && errno == EAGAIN, 0) + /* The socket is still receiving data. Wait a bit more. */ + && wait_on_socket (fd, EXTRA_RECEIVE_TIME) > 0) + goto again; + + break; + } ret += r; } while (ret < total); @@ -187,36 +250,6 @@ __nscd_unmap (struct mapped_database *mapped) } -static int -wait_on_socket (int sock) -{ - struct pollfd fds[1]; - fds[0].fd = sock; - fds[0].events = POLLIN | POLLERR | POLLHUP; - int n = __poll (fds, 1, 5 * 1000); - if (n == -1 && __builtin_expect (errno == EINTR, 0)) - { - /* Handle the case where the poll() call is interrupted by a - signal. We cannot just use TEMP_FAILURE_RETRY since it might - lead to infinite loops. */ - struct timeval now; - (void) __gettimeofday (&now, NULL); - long int end = (now.tv_sec + 5) * 1000 + (now.tv_usec + 500) / 1000; - while (1) - { - long int timeout = end - (now.tv_sec * 1000 - + (now.tv_usec + 500) / 1000); - n = __poll (fds, 1, timeout); - if (n != -1 || errno != EINTR) - break; - (void) __gettimeofday (&now, NULL); - } - } - - return n; -} - - /* Try to get a file descriptor for the shared meory segment containing the database. */ static struct mapped_database * @@ -265,7 +298,7 @@ get_mapping (request_type type, const char *key, msg.msg_controllen = cmsg->cmsg_len; - if (wait_on_socket (sock) <= 0) + if (wait_on_socket (sock, 5 * 1000) <= 0) goto out_close2; # ifndef MSG_CMSG_CLOEXEC @@ -497,7 +530,7 @@ __nscd_open_socket (const char *key, size_t keylen, request_type type, if (sock >= 0) { /* Wait for data. */ - if (wait_on_socket (sock) > 0) + if (wait_on_socket (sock, 5 * 1000) > 0) { ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, response, responselen)); |