about summary refs log tree commit diff
path: root/nscd/connections.c
diff options
context:
space:
mode:
Diffstat (limited to 'nscd/connections.c')
-rw-r--r--nscd/connections.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/nscd/connections.c b/nscd/connections.c
index bef1c16d1e..0afc95a227 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -51,6 +51,7 @@
 #include "nscd.h"
 #include "dbg_log.h"
 #include "selinux.h"
+#include <resolv/resolv.h>
 #ifdef HAVE_SENDFILE
 # include <kernel-features.h>
 #endif
@@ -228,6 +229,9 @@ static int sock;
 #ifdef HAVE_INOTIFY
 /* Inotify descriptor.  */
 static int inotify_fd = -1;
+
+/* Watch descriptor for resolver configuration file.  */
+static int resolv_conf_descr = -1;
 #endif
 
 /* Number of times clients had to wait.  */
@@ -824,7 +828,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
 	if (dbs[cnt].check_file)
 	  {
 #ifdef HAVE_INOTIFY
-	    if (inotify_fd == -1
+	    if (inotify_fd < 0
 		|| (dbs[cnt].inotify_descr
 		    = inotify_add_watch (inotify_fd, dbs[cnt].filename,
 					 IN_DELETE_SELF | IN_MODIFY)) < 0)
@@ -845,6 +849,14 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
 		  dbs[cnt].file_mtime = st.st_mtime;
 	      }
 	  }
+
+#ifdef HAVE_INOTIFY
+	if (cnt == hstdb && inotify_fd >= -1)
+	  /* We also monitor the resolver configuration file.  */
+	  resolv_conf_descr = inotify_add_watch (inotify_fd,
+						 _PATH_RESCONF,
+						 IN_DELETE_SELF | IN_MODIFY);
+#endif
       }
 
   /* Create the socket.  */
@@ -1798,6 +1810,7 @@ main_loop_poll (void)
 	    {
 	      if (conns[1].revents != 0)
 		{
+		  bool done[lastdb] = { false, };
 		  union
 		  {
 		    struct inotify_event i;
@@ -1806,16 +1819,25 @@ main_loop_poll (void)
 
 		  while (TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
 						   sizeof (inev)))
-			 >= sizeof (struct inotify_event))
+			 >= (ssize_t) sizeof (struct inotify_event))
 		    {
 		      /* Check which of the files changed.  */
 		      for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)
-			if (inev.i.wd == dbs[dbcnt].inotify_descr)
+			if (!done[dbcnt]
+			    && (inev.i.wd == dbs[dbcnt].inotify_descr
+				|| (dbcnt == hstdb
+				    && inev.i.wd == resolv_conf_descr)))
 			  {
-			    pthread_mutex_trylock (&dbs[dbcnt].prune_lock);
+			    if (dbcnt == hstdb
+				&& inev.i.wd == resolv_conf_descr)
+			      res_init ();
+
+			    pthread_mutex_lock (&dbs[dbcnt].prune_lock);
 			    dbs[dbcnt].clear_cache = 1;
 			    pthread_mutex_unlock (&dbs[dbcnt].prune_lock);
 			    pthread_cond_signal (&dbs[dbcnt].prune_cond);
+
+			    done[dbcnt] = true;
 			    break;
 			  }
 		    }
@@ -1952,7 +1974,7 @@ main_loop_epoll (int efd)
 
 	    while (TEMP_FAILURE_RETRY (read (inotify_fd, &inev,
 					     sizeof (inev)))
-		   >= sizeof (struct inotify_event))
+		   >= (ssize_t) sizeof (struct inotify_event))
 	      {
 		/* Check which of the files changed.  */
 		for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt)