chiark / gitweb /
common: Avoid warning about implicit declaration of gnupg_fd_valid.
[gnupg2.git] / scd / scdaemon.c
index 74fed44543ce489cd4b614f40ef79fe4ce93b2bb..02f0e722160c60106ea13c01feacc4fa68db7577 100644 (file)
@@ -52,6 +52,7 @@
 #include "ccid-driver.h"
 #include "gc-opt-flags.h"
 #include "asshelp.h"
+#include "exechelp.h"
 #include "../common/init.h"
 
 #ifndef ENAMETOOLONG
@@ -224,7 +225,8 @@ static assuan_sock_nonce_t socket_nonce;
    disabled but it won't perform any ticker specific actions. */
 static int ticker_disabled;
 
-
+/* FD to notify update of usb devices.  */
+static int notify_fd;
 \f
 static char *create_socket_name (char *standard_name);
 static gnupg_fd_t create_server_socket (const char *name,
@@ -1181,6 +1183,16 @@ start_connection_thread (void *arg)
 }
 
 
+void
+scd_kick_the_loop (void)
+{
+  int ret;
+
+  /* Kick the select loop.  */
+  ret = write (notify_fd, "", 1);
+  (void)ret;
+}
+
 /* Connection handler loop.  Wait for connection requests and spawn a
    thread after accepting a connection.  LISTEN_FD is allowed to be -1
    in which case this code will only do regular timeouts and handle
@@ -1202,9 +1214,23 @@ handle_connections (int listen_fd)
 #ifndef HAVE_W32_SYSTEM
   int signo;
 #endif
+  int pipe_fd[2];
+
+  ret = gnupg_create_pipe (pipe_fd);
+  if (ret)
+    {
+      log_error ("pipe creation failed: %s\n", gpg_strerror (ret));
+      return;
+    }
+  notify_fd = pipe_fd[1];
 
   ret = npth_attr_init(&tattr);
-  /* FIXME: Check error.  */
+  if (ret)
+    {
+      log_error ("npth_attr_init failed: %s\n", strerror (ret));
+      return;
+    }
+
   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
 
 #ifndef HAVE_W32_SYSTEM
@@ -1233,6 +1259,8 @@ handle_connections (int listen_fd)
 
   for (;;)
     {
+      int max_fd;
+
       if (shutdown_pending)
         {
           if (active_connections == 0)
@@ -1261,14 +1289,20 @@ handle_connections (int listen_fd)
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
+      FD_SET (pipe_fd[0], &read_fdset);
+      if (nfd < pipe_fd[0])
+        max_fd = pipe_fd[0];
+      else
+        max_fd = nfd;
+
 #ifndef HAVE_W32_SYSTEM
-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+      ret = npth_pselect (max_fd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
       saved_errno = errno;
 
       while (npth_sigev_get_pending(&signo))
        handle_signal (signo);
 #else
-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+      ret = npth_eselect (max_fd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
       saved_errno = errno;
 #endif
 
@@ -1284,6 +1318,13 @@ handle_connections (int listen_fd)
        /* Timeout.  Will be handled when calculating the next timeout.  */
        continue;
 
+      if (FD_ISSET (pipe_fd[0], &read_fdset))
+        {
+          char buf[256];
+
+          ret = read (pipe_fd[0], buf, sizeof buf);
+        }
+
       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
        {
           ctrl_t ctrl;
@@ -1322,6 +1363,8 @@ handle_connections (int listen_fd)
        }
     }
 
+  close (pipe_fd[0]);
+  close (pipe_fd[1]);
   cleanup ();
   log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
   npth_attr_destroy (&tattr);