wait. */
assert (fd != -1);
- TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+ writeall (fd, &dataset->resp, total);
}
goto out;
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)
{
/* 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);
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)
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)
{
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
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
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+ written = writeall (fd, &dataset->resp, total);
}
#include <sys/types.h>
#include <atomic.h>
#include <nscd-types.h>
+#include <sys/uio.h>
/* Version number of the daemon interface */
size_t keylen,
const struct mapped_database *mapped);
+/* Wrappers around read, readv and write that only read/write less than LEN
+ bytes on error or EOF. */
+extern ssize_t __readall (int fd, void *buf, size_t len)
+ attribute_hidden;
+extern ssize_t __readvall (int fd, const struct iovec *iov, int iovcnt)
+ attribute_hidden;
+extern ssize_t writeall (int fd, const void *buf, size_t len)
+ attribute_hidden;
+
#endif /* nscd.h */
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;
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;
}
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. */
++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
/* 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;
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))
{
#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)
{
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;
}
unnecessarily let the receiver wait. */
assert (fd != -1);
- written = TEMP_FAILURE_RETRY (write (fd, &dataset->resp, total));
+ written = writeall (fd, &dataset->resp, total);
}