about summary refs log tree commit diff
path: root/nscd
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-08-24 07:23:32 +0000
committerJakub Jelinek <jakub@redhat.com>2005-08-24 07:23:32 +0000
commit8bf34d8a27ffed48c7a43b7c7347235d389b0946 (patch)
tree36a2efd2a73c3d642829770b47f753e0160dd411 /nscd
parentd2b0f6344275bc3624e47a4d02b67a7e131f6f56 (diff)
downloadglibc-8bf34d8a27ffed48c7a43b7c7347235d389b0946.tar.gz
glibc-8bf34d8a27ffed48c7a43b7c7347235d389b0946.tar.xz
glibc-8bf34d8a27ffed48c7a43b7c7347235d389b0946.zip
Updated to fedora-glibc-20050824T0705
Diffstat (limited to 'nscd')
-rw-r--r--nscd/aicache.c2
-rw-r--r--nscd/connections.c32
-rw-r--r--nscd/grpcache.c3
-rw-r--r--nscd/hstcache.c3
-rw-r--r--nscd/initgrcache.c3
-rw-r--r--nscd/mem.c18
-rw-r--r--nscd/nscd.c15
-rw-r--r--nscd/nscd.conf4
-rw-r--r--nscd/nscd.h17
-rw-r--r--nscd/nscd_conf.c163
-rw-r--r--nscd/nscd_stat.c6
-rw-r--r--nscd/pwdcache.c3
12 files changed, 161 insertions, 108 deletions
diff --git a/nscd/aicache.c b/nscd/aicache.c
index fb75dc199d..992c6ef023 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -399,7 +399,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
       total = sizeof (notfound);
 
       if (fd != -1)
-	TEMP_FAILURE_RETRY (write (fd, &notfound, total));
+	TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
 
       dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
       /* If we cannot permanently store the result, so be it.  */
diff --git a/nscd/connections.c b/nscd/connections.c
index 33cde99cdf..900dfb1a4c 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -48,10 +48,6 @@
 #include "selinux.h"
 
 
-/* Number of bytes of data we initially reserve for each hash table bucket.  */
-#define DEFAULT_DATASIZE_PER_BUCKET 1024
-
-
 /* Wrapper functions with error checking for standard functions.  */
 extern void *xmalloc (size_t n);
 extern void *xcalloc (size_t n, size_t s);
@@ -104,6 +100,7 @@ struct database_dyn dbs[lastdb] =
     .check_file = 1,
     .persistent = 0,
     .shared = 0,
+    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/passwd",
     .db_filename = _PATH_NSCD_PASSWD_DB,
     .disabled_iov = &pwd_iov_disabled,
@@ -119,6 +116,7 @@ struct database_dyn dbs[lastdb] =
     .check_file = 1,
     .persistent = 0,
     .shared = 0,
+    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/group",
     .db_filename = _PATH_NSCD_GROUP_DB,
     .disabled_iov = &grp_iov_disabled,
@@ -134,6 +132,7 @@ struct database_dyn dbs[lastdb] =
     .check_file = 1,
     .persistent = 0,
     .shared = 0,
+    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/hosts",
     .db_filename = _PATH_NSCD_HOSTS_DB,
     .disabled_iov = &hst_iov_disabled,
@@ -188,7 +187,7 @@ writeall (int fd, const void *buf, size_t len)
   ssize_t ret;
   do
     {
-      ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
+      ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
       if (ret <= 0)
 	break;
       buf = (const char *) buf + ret;
@@ -473,8 +472,16 @@ nscd_init (void)
 			     _("file size does not match"));
 		    unlink (dbs[cnt].db_filename);
 		  }
-		else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
-				      MAP_SHARED, fd, 0)) == MAP_FAILED)
+		/* Note we map with the maximum size allowed for the
+		   database.  This is likely much larger than the
+		   actual file size.  This is OK on most OSes since
+		   extensions of the underlying file will
+		   automatically translate more pages available for
+		   memory access.  */
+		else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
+				      PROT_READ | PROT_WRITE,
+				      MAP_SHARED, fd, 0))
+			 == MAP_FAILED)
 		  goto fail_db;
 		else if (!verify_persistent_db (mem, &head, cnt))
 		  {
@@ -638,8 +645,10 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
 
 		if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
 		     != sizeof (head))
-		    || posix_fallocate (fd, 0, total) != 0
-		    || (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
+		    || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
+			!= 0)
+		    || (mem = mmap (NULL, dbs[cnt].max_db_size,
+				    PROT_READ | PROT_WRITE,
 				    MAP_SHARED, fd, 0)) == MAP_FAILED)
 		  {
 		  write_fail:
@@ -901,8 +910,9 @@ cannot handle old request version %d; current version is %d"),
       if (!db->enabled)
 	{
 	  /* No, sent the prepared record.  */
-	  if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
-					 db->disabled_iov->iov_len))
+	  if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
+					db->disabled_iov->iov_len,
+					MSG_NOSIGNAL))
 	      != (ssize_t) db->disabled_iov->iov_len
 	      && __builtin_expect (debug_level, 0) > 0)
 	    {
diff --git a/nscd/grpcache.c b/nscd/grpcache.c
index c938554b25..6543ef354d 100644
--- a/nscd/grpcache.c
+++ b/nscd/grpcache.c
@@ -107,7 +107,8 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
 	     case.  */
 	  total = sizeof (notfound);
 
-	  written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
+	  written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+					      MSG_NOSIGNAL));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 377f02387d..29bce99819 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -115,7 +115,8 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
 	  written = total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
+	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						MSG_NOSIGNAL));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index db01f1bc28..bb6dee2b4e 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -188,7 +188,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 	  /* We have no data.  This means we send the standard reply for this
 	     case.  */
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
+	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						MSG_NOSIGNAL));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */
diff --git a/nscd/mem.c b/nscd/mem.c
index 823eda1019..96f0170c6c 100644
--- a/nscd/mem.c
+++ b/nscd/mem.c
@@ -481,18 +481,26 @@ mempool_alloc (struct database_dyn *db, size_t len)
       if (! tried_resize)
 	{
 	  /* Try to resize the database.  Grow size of 1/8th.  */
-	  size_t new_data_size = db->head->data_size + db->head->data_size / 8;
 	  size_t oldtotal = (sizeof (struct database_pers_head)
 			     + db->head->module * sizeof (ref_t)
 			     + db->head->data_size);
+	  size_t new_data_size = (db->head->data_size
+				  + MAX (2 * len, db->head->data_size / 8));
 	  size_t newtotal = (sizeof (struct database_pers_head)
 			     + db->head->module * sizeof (ref_t)
 			     + new_data_size);
+	  if (newtotal > db->max_db_size)
+	    {
+	      new_data_size -= newtotal - db->max_db_size;
+	      newtotal = db->max_db_size;
+	    }
 
-	  if ((!db->mmap_used
-	       || posix_fallocate (db->wr_fd, oldtotal, newtotal) != 0)
-	      /* Try to resize the mapping.  Note: no MREMAP_MAYMOVE.  */
-	      && mremap (db->head, oldtotal, newtotal, 0) == 0)
+	  if (db->mmap_used && newtotal > oldtotal
+	      /* We only have to adjust the file size.  The new pages
+		 become magically available.  */
+	      && TEMP_FAILURE_RETRY_VAL (posix_fallocate (db->wr_fd, oldtotal,
+							  newtotal
+							  - oldtotal)) == 0)
 	    {
 	      db->head->data_size = new_data_size;
 	      tried_resize = true;
diff --git a/nscd/nscd.c b/nscd/nscd.c
index 4d14f06ecf..8f299a3aa4 100644
--- a/nscd/nscd.c
+++ b/nscd/nscd.c
@@ -153,12 +153,10 @@ main (int argc, char **argv)
 
   /* Read the configuration file.  */
   if (nscd_parse_file (conffile, dbs) != 0)
-    {
-      /* We couldn't read the configuration file.  We don't start the
-	 server.  */
-      dbg_log (_("cannot read configuration file; this is fatal"));
-      exit (1);
-    }
+    /* We couldn't read the configuration file.  We don't start the
+       server.  */
+    error (EXIT_FAILURE, 0,
+	   _("failure while reading configuration file; this is fatal"));
 
   /* Do we only get statistics?  */
   if (get_stats)
@@ -319,8 +317,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	req.version = NSCD_VERSION;
 	req.type = SHUTDOWN;
 	req.key_len = 0;
-	nbytes = TEMP_FAILURE_RETRY (write (sock, &req,
-					    sizeof (request_header)));
+	nbytes = TEMP_FAILURE_RETRY (send (sock, &req,
+					   sizeof (request_header),
+					   MSG_NOSIGNAL));
 	close (sock);
 	exit (nbytes != sizeof (request_header) ? EXIT_FAILURE : EXIT_SUCCESS);
       }
diff --git a/nscd/nscd.conf b/nscd/nscd.conf
index 9cb9fa292d..bde8e36219 100644
--- a/nscd/nscd.conf
+++ b/nscd/nscd.conf
@@ -23,6 +23,7 @@
 #	check-files		<service> <yes|no>
 #	persistent		<service> <yes|no>
 #	shared			<service> <yes|no>
+#	max-db-szie		<service> <number bytes>
 #
 # Currently supported cache names (services): passwd, group, hosts
 #
@@ -45,6 +46,7 @@
 	check-files		passwd		yes
 	persistent		passwd		yes
 	shared			passwd		yes
+	max-db-size		passwd		33554432
 
 	enable-cache		group		yes
 	positive-time-to-live	group		3600
@@ -53,6 +55,7 @@
 	check-files		group		yes
 	persistent		group		yes
 	shared			group		yes
+	max-db-size		group		33554432
 
 	enable-cache		hosts		yes
 	positive-time-to-live	hosts		3600
@@ -61,3 +64,4 @@
 	check-files		hosts		yes
 	persistent		hosts		yes
 	shared			hosts		yes
+	max-db-size		hosts		33554432
diff --git a/nscd/nscd.h b/nscd/nscd.h
index 25a4b38eb4..3859d95d01 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -63,6 +63,7 @@ struct database_dyn
   int check_file;
   int persistent;
   int shared;
+  size_t max_db_size;
   const char *filename;
   const char *db_filename;
   time_t file_mtime;
@@ -99,6 +100,12 @@ struct database_dyn
 #define BLOCK_ALIGN (1 << BLOCK_ALIGN_LOG)
 #define BLOCK_ALIGN_M1 (BLOCK_ALIGN - 1)
 
+/* Default value for the maximum size of the database files.  */
+#define DEFAULT_MAX_DB_SIZE	(32 * 1024 * 1024)
+
+/* Number of bytes of data we initially reserve for each hash table bucket.  */
+#define DEFAULT_DATASIZE_PER_BUCKET 1024
+
 
 /* Global variables.  */
 extern struct database_dyn dbs[lastdb];
@@ -241,4 +248,14 @@ extern void gc (struct database_dyn *db);
 /* nscd_setup_thread.c */
 extern void setup_thread (struct database_dyn *db);
 
+
+/* Special version of TEMP_FAILURE_RETRY for functions returning error
+   values.  */
+#define TEMP_FAILURE_RETRY_VAL(expression) \
+  (__extension__							      \
+    ({ long int __result;						      \
+       do __result = (long int) (expression);				      \
+       while (__result == EINTR);					      \
+       __result; }))
+
 #endif /* nscd.h */
diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
index d21f2fc501..1039250f48 100644
--- a/nscd/nscd_conf.c
+++ b/nscd/nscd_conf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
 
@@ -19,6 +19,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <error.h>
 #include <libintl.h>
 #include <malloc.h>
 #include <pwd.h>
@@ -45,6 +46,18 @@ const char *dbnames[lastdb] =
   [hstdb] = "hosts"
 };
 
+
+static int
+find_db (const char *name)
+{
+  for (int cnt = 0; cnt < lastdb; ++cnt)
+    if (strcmp (name, dbnames[cnt]) == 0)
+      return cnt;
+
+  error (0, 0, _("database %s is not supported\n"), name);
+  return -1;
+}
+
 int
 nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 {
@@ -52,6 +65,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
   char *line, *cp, *entry, *arg1, *arg2;
   size_t len;
   int cnt;
+  const unsigned int initial_error_message_count = error_message_count;
 
   /* Open the configuration file.  */
   fp = fopen (fname, "r");
@@ -91,7 +105,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
       ++arg1;
       *cp = '\0';
       if (strlen (entry) == 0)
-	dbg_log (_("Parse error: %s"), line);
+	error (0, 0, _("Parse error: %s"), line);
       while (isspace (*arg1) && *arg1 != '\0')
 	++arg1;
       cp = arg1;
@@ -112,64 +126,49 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 
       if (strcmp (entry, "positive-time-to-live") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		dbs[cnt].postimeout = atol (arg2);
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    dbs[idx].postimeout = atol (arg2);
 	}
       else if (strcmp (entry, "negative-time-to-live") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		dbs[cnt].negtimeout = atol (arg2);
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    dbs[idx].negtimeout = atol (arg2);
 	}
       else if (strcmp (entry, "suggested-size") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		dbs[cnt].suggested_module = atol (arg2);
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    dbs[idx].suggested_module = atol (arg2);
 	}
       else if (strcmp (entry, "enable-cache") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		if (strcmp (arg2, "no") == 0)
-		  dbs[cnt].enabled = 0;
-		else if (strcmp (arg2, "yes") == 0)
-		  dbs[cnt].enabled = 1;
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    {
+	      if (strcmp (arg2, "no") == 0)
+		dbs[idx].enabled = 0;
+	      else if (strcmp (arg2, "yes") == 0)
+		dbs[idx].enabled = 1;
+	    }
 	}
       else if (strcmp (entry, "check-files") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		if (strcmp (arg2, "no") == 0)
-		  dbs[cnt].check_file = 0;
-		else if (strcmp (arg2, "yes") == 0)
-		  dbs[cnt].check_file = 1;
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    {
+	      if (strcmp (arg2, "no") == 0)
+		dbs[idx].check_file = 0;
+	      else if (strcmp (arg2, "yes") == 0)
+		dbs[idx].check_file = 1;
+	    }
+	}
+      else if (strcmp (entry, "max-db-size") == 0)
+	{
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    dbs[idx].max_db_size = atol (arg2);
 	}
       else if (strcmp (entry, "logfile") == 0)
 	set_logfile (arg1);
@@ -191,14 +190,14 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
       else if (strcmp (entry, "server-user") == 0)
         {
           if (!arg1)
-            dbg_log (_("Must specify user name for server-user option"));
+            error (0, 0, _("Must specify user name for server-user option"));
           else
             server_user = xstrdup (arg1);
         }
       else if (strcmp (entry, "stat-user") == 0)
         {
           if (arg1 == NULL)
-            dbg_log (_("Must specify user name for stat-user option"));
+            error (0, 0, _("Must specify user name for stat-user option"));
           else
 	    {
 	      stat_user = xstrdup (arg1);
@@ -210,31 +209,25 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
         }
       else if (strcmp (entry, "persistent") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		if (strcmp (arg2, "no") == 0)
-		  dbs[cnt].persistent = 0;
-		else if (strcmp (arg2, "yes") == 0)
-		  dbs[cnt].persistent = 1;
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    {
+	      if (strcmp (arg2, "no") == 0)
+		dbs[idx].persistent = 0;
+	      else if (strcmp (arg2, "yes") == 0)
+		dbs[idx].persistent = 1;
+	    }
 	}
       else if (strcmp (entry, "shared") == 0)
 	{
-	  for (cnt = 0; cnt < lastdb; ++cnt)
-	    if (strcmp (arg1, dbnames[cnt]) == 0)
-	      {
-		if (strcmp (arg2, "no") == 0)
-		  dbs[cnt].shared = 0;
-		else if (strcmp (arg2, "yes") == 0)
-		  dbs[cnt].shared = 1;
-		break;
-	      }
-	  if (cnt == lastdb)
-	    dbg_log ("database %s is not supported\n", arg1);
+	  int idx = find_db (arg1);
+	  if (idx >= 0)
+	    {
+	      if (strcmp (arg2, "no") == 0)
+		dbs[idx].shared = 0;
+	      else if (strcmp (arg2, "yes") == 0)
+		dbs[idx].shared = 1;
+	    }
 	}
       else if (strcmp (entry, "reload-count") == 0)
 	{
@@ -248,7 +241,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	      else if (count >= 0)
 	    reload_count = count;
 	      else
-		dbg_log (_("invalid value for 'reload-count': %u"), count);
+		error (0, 0, _("invalid value for 'reload-count': %u"), count);
 	    }
 	}
       else if (strcmp (entry, "paranoia") == 0)
@@ -263,10 +256,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 	  if (arg1 != NULL)
 	    restart_interval = atol (arg1);
 	  else
-            dbg_log (_("Must specify value for restart-interval option"));
+            error (0, 0, _("Must specify value for restart-interval option"));
 	}
       else
-	dbg_log (_("Unknown option: %s %s %s"), entry, arg1, arg2);
+	error (0, 0, _("Unknown option: %s %s %s"), entry, arg1, arg2);
     }
   while (!feof_unlocked (fp));
 
@@ -279,7 +272,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
       oldcwd = get_current_dir_name ();
       if (oldcwd == NULL)
 	{
-	  dbg_log (_("\
+	  error (0, 0, _("\
 cannot get current working directory: %s; disabling paranoia mode"),
 		   strerror (errno));
 	  paranoia = 0;
@@ -290,10 +283,26 @@ cannot get current working directory: %s; disabling paranoia mode"),
   if (max_nthreads < nthreads)
     max_nthreads = nthreads;
 
+  for (cnt = 0; cnt < lastdb; ++cnt)
+    {
+      size_t datasize = (sizeof (struct database_pers_head)
+			 + roundup (dbs[cnt].suggested_module
+				    * sizeof (ref_t), ALIGN)
+			 + (dbs[cnt].suggested_module
+			    * DEFAULT_DATASIZE_PER_BUCKET));
+      if (datasize > dbs[cnt].max_db_size)
+	{
+	  error (0, 0, _("maximum file size for %s database too small"),
+		   dbnames[cnt]);
+	  dbs[cnt].max_db_size = datasize;
+	}
+
+    }
+
   /* Free the buffer.  */
   free (line);
   /* Close configuration file.  */
   fclose (fp);
 
-  return 0;
+  return error_message_count != initial_error_message_count;
 }
diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
index 43f6266c6e..c1d0bffe20 100644
--- a/nscd/nscd_stat.c
+++ b/nscd/nscd_stat.c
@@ -133,7 +133,8 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
   if (selinux_enabled)
     nscd_avc_cache_stats (&data.cstats);
 
-  if (TEMP_FAILURE_RETRY (write (fd, &data, sizeof (data))) != sizeof (data))
+  if (TEMP_FAILURE_RETRY (send (fd, &data, sizeof (data), MSG_NOSIGNAL))
+      != sizeof (data))
     {
       char buf[256];
       dbg_log (_("cannot write statistics: %s"),
@@ -180,7 +181,8 @@ receive_print_stats (void)
   req.version = NSCD_VERSION;
   req.type = GETSTAT;
   req.key_len = 0;
-  nbytes = TEMP_FAILURE_RETRY (write (fd, &req, sizeof (request_header)));
+  nbytes = TEMP_FAILURE_RETRY (send (fd, &req, sizeof (request_header),
+				     MSG_NOSIGNAL));
   if (nbytes != sizeof (request_header))
     {
       int err = errno;
diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c
index 34265c3f39..6b25968f71 100644
--- a/nscd/pwdcache.c
+++ b/nscd/pwdcache.c
@@ -114,7 +114,8 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
 	  written = total = sizeof (notfound);
 
 	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (write (fd, &notfound, total));
+	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+						MSG_NOSIGNAL));
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
 	  /* If we cannot permanently store the result, so be it.  */