about summary refs log tree commit diff
path: root/nscd
diff options
context:
space:
mode:
Diffstat (limited to 'nscd')
-rw-r--r--nscd/aicache.c4
-rw-r--r--nscd/connections.c26
-rw-r--r--nscd/grpcache.c2
-rw-r--r--nscd/hstcache.c2
-rw-r--r--nscd/initgrcache.c4
-rw-r--r--nscd/nscd_getai.c3
-rw-r--r--nscd/nscd_getgr_r.c7
-rw-r--r--nscd/nscd_gethst_r.c8
-rw-r--r--nscd/nscd_getpw_r.c4
-rw-r--r--nscd/nscd_helper.c58
-rw-r--r--nscd/nscd_initgroups.c5
-rw-r--r--nscd/pwdcache.c2
12 files changed, 97 insertions, 28 deletions
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 4e0496ff44..bdd2a9b371 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -1,5 +1,5 @@
 /* Cache handling for host lookup.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -365,7 +365,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
 		     wait.  */
 		  assert (fd != -1);
 
-		  TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+		  writeall (fd, &dataset->resp, total);
 		}
 
 	      goto out;
diff --git a/nscd/connections.c b/nscd/connections.c
index 63a01e3bb6..86069b237a 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -181,13 +181,28 @@ static int sock;
 unsigned long int client_queued;
 
 
+ssize_t
+writeall (int fd, const void *buf, size_t len)
+{
+  size_t n = len;
+  ssize_t ret;
+  do
+    {
+      ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
+      if (ret <= 0)
+	break;
+      buf = (const char *) buf + ret;
+      n -= ret;
+    }
+  while (n > 0);
+  return ret < 0 ? ret : len - n;
+}
+
+
 /* Initialize database information structures.  */
 void
 nscd_init (void)
 {
-  struct sockaddr_un sock_addr;
-  size_t cnt;
-
   /* Secure mode and unprivileged mode are incompatible */
   if (server_user != NULL && secure_in_use)
     {
@@ -204,7 +219,7 @@ nscd_init (void)
     /* No configuration for this value, assume a default.  */
     nthreads = 2 * lastdb;
 
-  for (cnt = 0; cnt < lastdb; ++cnt)
+  for (size_t cnt = 0; cnt < lastdb; ++cnt)
     if (dbs[cnt].enabled)
       {
 	pthread_rwlock_init (&dbs[cnt].lock, NULL);
@@ -500,6 +515,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
       exit (1);
     }
   /* Bind a name to the socket.  */
+  struct sockaddr_un sock_addr;
   sock_addr.sun_family = AF_UNIX;
   strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
   if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
@@ -691,7 +707,7 @@ cannot handle old request version %d; current version is %d"),
       if (cached != NULL)
 	{
 	  /* Hurray it's in the cache.  */
-	  if (TEMP_FAILURE_RETRY (write (fd, cached->data, cached->recsize))
+	  if (writeall (fd, cached->data, cached->recsize)
 	      != cached->recsize
 	      && __builtin_expect (debug_level, 0) > 0)
 	    {
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index ed84d92120..5d327f360c 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -292,7 +292,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily let the receiver wait.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
       /* Add the record to the database.  But only if it has not been
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index a18860a53d..377f02387d 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -327,7 +327,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily keep the receiver waiting.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
       /* Add the record to the database.  But only if it has not been
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index b46433716b..db01f1bc28 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -1,5 +1,5 @@
 /* Cache handling for host lookup.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -343,7 +343,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily let the receiver wait.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}
 
 
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c
index 866f7b2a5f..4e3dfad1ea 100644
--- a/nscd/nscd_getai.c
+++ b/nscd/nscd_getai.c
@@ -119,8 +119,7 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
       if (respdata == NULL)
 	{
 	  /* Read the data from the socket.  */
-	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock, resultbuf + 1,
-						   datalen)) == datalen)
+	  if ((size_t) __readall (sock, resultbuf + 1, datalen) == datalen)
 	    {
 	      retval = 0;
 	      *result = resultbuf;
diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c
index 282912db3e..dae1c0da54 100644
--- a/nscd/nscd_getgr_r.c
+++ b/nscd/nscd_getgr_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
+/* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
@@ -202,7 +202,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
 	  total_len = vec[0].iov_len + vec[1].iov_len;
 
 	  /* Get this data.  */
-	  size_t n = TEMP_FAILURE_RETRY (__readv (sock, vec, 2));
+	  size_t n = __readvall (sock, vec, 2);
 	  if (__builtin_expect (n != total_len, 0))
 	    goto out_close;
 	}
@@ -232,8 +232,7 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type,
       retval = 0;
       if (gr_name == NULL)
 	{
-	  size_t n = TEMP_FAILURE_RETRY (__read (sock, resultbuf->gr_mem[0],
-						 total_len));
+	  size_t n = __readall (sock, resultbuf->gr_mem[0], total_len);
 	  if (__builtin_expect (n != total_len, 0))
 	    {
 	      /* The `errno' to some value != ERANGE.  */
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index ef27e68735..70ee38b71f 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -299,8 +299,7 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
 	      ++n;
 	    }
 
-	  if ((size_t) TEMP_FAILURE_RETRY (__readv (sock, vec, n))
-	      != total_len)
+	  if ((size_t) __readvall (sock, vec, n) != total_len)
 	    goto out_close;
 	}
       else
@@ -329,9 +328,8 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type,
       /* And finally read the aliases.  */
       if (addr_list == NULL)
 	{
-	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock,
-						   resultbuf->h_aliases[0],
-						   total_len)) == total_len)
+	  if ((size_t) __readall (sock, resultbuf->h_aliases[0], total_len)
+	      == total_len)
 	    {
 	      retval = 0;
 	      *result = resultbuf;
diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c
index fe5fb43ca1..61a712c6b4 100644
--- a/nscd/nscd_getpw_r.c
+++ b/nscd/nscd_getpw_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
 
@@ -172,7 +172,7 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type,
       retval = 0;
       if (pw_name == NULL)
 	{
-	  ssize_t nbytes = TEMP_FAILURE_RETRY (__read (sock, buffer, total));
+	  ssize_t nbytes = __readall (sock, buffer, total);
 
 	  if (__builtin_expect (nbytes != total, 0))
 	    {
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)
 {
diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c
index daddf2e164..cf5af6edc1 100644
--- a/nscd/nscd_initgroups.c
+++ b/nscd/nscd_initgroups.c
@@ -110,9 +110,8 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size,
       if (respdata == NULL)
 	{
 	  /* Read the data from the socket.  */
-	  if ((size_t) TEMP_FAILURE_RETRY (__read (sock, *groupsp,
-						   initgr_resp->ngrps
-						   * sizeof (gid_t)))
+	  if ((size_t) __readall (sock, *groupsp, initgr_resp->ngrps
+						  * sizeof (gid_t))
 	      == initgr_resp->ngrps * sizeof (gid_t))
 	    retval = initgr_resp->ngrps;
 	}
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index b67b0f2b43..34265c3f39 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -287,7 +287,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	     unnecessarily let the receiver wait.  */
 	  assert (fd != -1);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+	  written = writeall (fd, &dataset->resp, total);
 	}