diff options
Diffstat (limited to 'nscd/nscd_helper.c')
-rw-r--r-- | nscd/nscd_helper.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c index ea4fb968db..c99cb430aa 100644 --- a/nscd/nscd_helper.c +++ b/nscd/nscd_helper.c @@ -34,6 +34,64 @@ #include "nscd-client.h" +ssize_t +__readall (int fd, void *buf, size_t len) +{ + size_t n = len; + ssize_t ret; + do + { + ret = TEMP_FAILURE_RETRY (__read (fd, buf, n)); + if (ret <= 0) + break; + buf = (char *) buf + ret; + n -= ret; + } + while (n > 0); + return ret < 0 ? ret : len - n; +} + + +ssize_t +__readvall (int fd, const struct iovec *iov, int iovcnt) +{ + ssize_t ret = TEMP_FAILURE_RETRY (__readv (fd, iov, iovcnt)); + if (ret <= 0) + return ret; + + size_t total = 0; + for (int i = 0; i < iovcnt; ++i) + total += iov[i].iov_len; + + if (ret < total) + { + struct iovec iov_buf[iovcnt]; + ssize_t r = ret; + + struct iovec *iovp = memcpy (iov_buf, iov, iovcnt * sizeof (*iov)); + do + { + while (iovp->iov_len <= r) + { + r -= iovp->iov_len; + --iovcnt; + ++iovp; + } + iovp->iov_base = (char *) iovp->iov_base + r; + iovp->iov_len -= r; + r = TEMP_FAILURE_RETRY (__readv (fd, iovp, iovcnt)); + if (r <= 0) + break; + ret += r; + } + while (ret < total); + if (r < 0) + ret = r; + } + return ret; +} + + static int open_socket (void) { |