[git] GnuPG - branch, master, updated. gnupg-2.1.18-23-g881dcdf

by NIIBE Yutaka cvs at cvs.gnupg.org
Thu Jan 26 14:13:54 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  881dcdfd84ebad36bff20c895e629025bed9d94e (commit)
      from  9b06633c811e8815c07d744f20b45405cb082367 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 881dcdfd84ebad36bff20c895e629025bed9d94e
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu Jan 26 22:02:41 2017 +0900

    scd: Only submit apdu_get_status when needed.
    
    * scd/apdu.c (apdu_dev_list_finish): Return Boolean value if
    all device support INTERRUPT transfer.
    * scd/ccid-driver.c (ccid_dev_scan_finish): Likewise.
    * scd/app.c (app_new_register): Fix initial value of card_status.
    (select_application): Call update_fdset_for_usb.
    (scd_update_reader_status_file): Ditto.
    * scd/scdaemon.c (update_fdset_for_usb, need_tick): New.
    (handle_connections): Call handle_tick when select returns.
    Let select watch USB file descriptors, too.
    Call libusb_handle_events_timeout_completed for INTERRUPT transfer.
    
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>

diff --git a/scd/apdu.c b/scd/apdu.c
index 38ebd2b..f88d970 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -2970,15 +2970,22 @@ apdu_dev_list_start (const char *portstr, struct dev_list **l_p)
   return 0;
 }
 
-void
+int
 apdu_dev_list_finish (struct dev_list *dl)
 {
+  int all_have_intr_endp;
+
 #ifdef HAVE_LIBUSB
   if (dl->ccid_table)
-    ccid_dev_scan_finish (dl->ccid_table, dl->idx_max);
+    all_have_intr_endp = ccid_dev_scan_finish (dl->ccid_table, dl->idx_max);
+  else
+    all_have_intr_endp = 0;
+#else
+  all_have_intr_endp = 0;
 #endif
   xfree (dl);
   npth_mutex_unlock (&reader_table_lock);
+  return all_have_intr_endp;
 }
 
 
diff --git a/scd/apdu.h b/scd/apdu.h
index 473def5..d71c8dd 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -88,7 +88,7 @@ struct dev_list;
 gpg_error_t apdu_init (void);
 
 gpg_error_t apdu_dev_list_start (const char *portstr, struct dev_list **l_p);
-void apdu_dev_list_finish (struct dev_list *l);
+int apdu_dev_list_finish (struct dev_list *l);
 
 /* Note, that apdu_open_reader returns no status word but -1 on error. */
 int apdu_open_reader (struct dev_list *l);
diff --git a/scd/app.c b/scd/app.c
index b10a452..daff0b7 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -192,6 +192,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name)
     }
 
   app->slot = slot;
+  app->card_status = (unsigned int)-1;
 
   if (npth_mutex_init (&app->lock, NULL))
     {
@@ -329,6 +330,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
   if (scan || !app_top)
     {
       struct dev_list *l;
+      int all_have_intr_endp;
 
       err = apdu_dev_list_start (opt.reader_port, &l);
       if (err)
@@ -368,7 +370,8 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
             }
         }
 
-      apdu_dev_list_finish (l);
+      all_have_intr_endp = apdu_dev_list_finish (l);
+      update_fdset_for_usb (1, all_have_intr_endp);
     }
 
   npth_mutex_lock (&app_list_lock);
@@ -1050,6 +1053,7 @@ scd_update_reader_status_file (void)
                   log_debug ("Removal of a card: %d\n", a->slot);
                   apdu_close_reader (a->slot);
                   deallocate_app (a);
+                  update_fdset_for_usb (0, 0);
                 }
               else
                 a->card_status = status;
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index ce55393..8ca8e96 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -1699,13 +1699,17 @@ ccid_dev_scan (int *idx_max_p, struct ccid_dev_table **t_p)
   return err;
 }
 
-void
+int
 ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max)
 {
+  int all_have_intr_endp = 1;
   int i;
 
   for (i = 0; i < max; i++)
     {
+      if (tbl[i].ep_intr == -1)
+        all_have_intr_endp = 0;
+
       free (tbl[i].ifcdesc_extra);
       tbl[i].transport = 0;
       tbl[i].n = 0;
@@ -1719,6 +1723,8 @@ ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max)
     }
   libusb_free_device_list (ccid_usb_dev_list, 1);
   ccid_usb_dev_list = NULL;
+
+  return all_have_intr_endp;
 }
 
 unsigned int
diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h
index 9e71f5e..8e9f9e2 100644
--- a/scd/ccid-driver.h
+++ b/scd/ccid-driver.h
@@ -115,7 +115,7 @@ int ccid_set_debug_level (int level);
 char *ccid_get_reader_list (void);
 
 gpg_error_t ccid_dev_scan (int *idx_max, struct ccid_dev_table **t_p);
-void ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max);
+int ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max);
 unsigned int ccid_get_BAI (int, struct ccid_dev_table *tbl);
 int ccid_compare_BAI (ccid_driver_t handle, unsigned int);
 int ccid_open_reader (const char *spec_reader_name,
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 74fed44..8e1f698 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -44,6 +44,10 @@
 
 #include <assuan.h> /* malloc hooks */
 
+#ifdef HAVE_LIBUSB
+#include <libusb.h>
+#endif
+
 #include "i18n.h"
 #include "sysutils.h"
 #include "app-common.h"
@@ -224,7 +228,17 @@ static assuan_sock_nonce_t socket_nonce;
    disabled but it won't perform any ticker specific actions. */
 static int ticker_disabled;
 
+/* Set of FD to select.  */
+static fd_set fdset;
+
+/* Max FD to select.  */
+static int nfd;
 
+/* Set if all usb devices have INTERRUPT endpoints.  */
+static int usb_all_have_intr_endp;
+
+/* FD to listen incomming connections.  */
+static int listen_fd;
 

 static char *create_socket_name (char *standard_name);
 static gnupg_fd_t create_server_socket (const char *name,
@@ -232,7 +246,7 @@ static gnupg_fd_t create_server_socket (const char *name,
                                         assuan_sock_nonce_t *nonce);
 
 static void *start_connection_thread (void *arg);
-static void handle_connections (int listen_fd);
+static void handle_connections (void);
 
 /* Pth wrapper function definitions. */
 ASSUAN_SYSTEM_NPTH_IMPL;
@@ -780,7 +794,8 @@ main (int argc, char **argv )
 
       /* We run handle_connection to wait for the shutdown signal and
          to run the ticker stuff.  */
-      handle_connections (fd);
+      listen_fd = fd;
+      handle_connections ();
       if (fd != -1)
         close (fd);
     }
@@ -912,7 +927,8 @@ main (int argc, char **argv )
 
 #endif /*!HAVE_W32_SYSTEM*/
 
-      handle_connections (fd);
+      listen_fd = fd;
+      handle_connections ();
 
       close (fd);
     }
@@ -1181,23 +1197,76 @@ start_connection_thread (void *arg)
 }
 
 
+void
+update_fdset_for_usb (int scanned, int all_have_intr_endp)
+{
+#ifdef HAVE_LIBUSB
+  const struct libusb_pollfd **pfd_array = libusb_get_pollfds (NULL);
+  const struct libusb_pollfd **p;
+#endif
+
+  if (scanned)
+    usb_all_have_intr_endp = all_have_intr_endp;
+
+  FD_ZERO (&fdset);
+  nfd = 0;
+
+  if (listen_fd != -1)
+    {
+      FD_SET (listen_fd, &fdset);
+      nfd = listen_fd;
+    }
+
+#ifdef HAVE_LIBUSB
+  for (p = pfd_array; *p; p++)
+    {
+      int fd = (*p)->fd;
+
+      FD_SET (fd, &fdset);
+      if (nfd < fd)
+        nfd = fd;
+      p++;
+    }
+
+  libusb_free_pollfds (pfd_array);
+#endif
+
+  log_debug ("update_fdset_for_usb (%d, %d): %d\n",
+             scanned, all_have_intr_endp, nfd);
+}
+
+static int
+need_tick (void)
+{
+  if (shutdown_pending)
+    return 1;
+
+  if (listen_fd != -1 && nfd == listen_fd)
+    return 1;
+
+  if (usb_all_have_intr_endp)
+    return 0;
+
+  return 1;
+}
+
 /* 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
    signals. */
 static void
-handle_connections (int listen_fd)
+handle_connections (void)
 {
   npth_attr_t tattr;
   struct sockaddr_un paddr;
   socklen_t plen;
-  fd_set fdset, read_fdset;
+  fd_set read_fdset;
   int ret;
   int fd;
-  int nfd;
   struct timespec abstime;
   struct timespec curtime;
   struct timespec timeout;
+  struct timespec *t;
   int saved_errno;
 #ifndef HAVE_W32_SYSTEM
   int signo;
@@ -1244,56 +1313,63 @@ handle_connections (int listen_fd)
              used to just wait on a signal or timeout event. */
           FD_ZERO (&fdset);
           listen_fd = -1;
-	}
+        }
 
-      npth_clock_gettime (&curtime);
-      if (!(npth_timercmp (&curtime, &abstime, <)))
-	{
-	  /* Timeout.  */
-	  handle_tick ();
-	  timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
-	  timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
-	  npth_timeradd (&curtime, &timeout, &abstime);
-	}
-      npth_timersub (&abstime, &curtime, &timeout);
+      if (need_tick ())
+        {
+          npth_clock_gettime (&curtime);
+          if (!(npth_timercmp (&curtime, &abstime, <)))
+            {
+              /* Timeout.  */
+              timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
+              timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
+              npth_timeradd (&curtime, &timeout, &abstime);
+            }
+          npth_timersub (&abstime, &curtime, &timeout);
+          t = &timeout;
+        }
+      else
+        t = NULL;
+
+      handle_tick ();
 
       /* POSIX says that fd_set should be implemented as a structure,
          thus a simple assignment is fine to copy the entire set.  */
       read_fdset = fdset;
 
 #ifndef HAVE_W32_SYSTEM
-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, t, npth_sigev_sigmask());
       saved_errno = errno;
 
       while (npth_sigev_get_pending(&signo))
-	handle_signal (signo);
+        handle_signal (signo);
 #else
-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, t, NULL, NULL);
       saved_errno = errno;
 #endif
 
       if (ret == -1 && saved_errno != EINTR)
-	{
+        {
           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
                      strerror (saved_errno));
           npth_sleep (1);
-	  continue;
-	}
+          continue;
+        }
 
       if (ret <= 0)
-	/* Timeout.  Will be handled when calculating the next timeout.  */
-	continue;
+        /* Timeout.  Will be handled when calculating the next timeout.  */
+        continue;
 
       if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
-	{
+        {
           ctrl_t ctrl;
 
           plen = sizeof paddr;
-	  fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
-	  if (fd == -1)
-	    {
-	      log_error ("accept failed: %s\n", strerror (errno));
-	    }
+          fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
+          if (fd == -1)
+            {
+              log_error ("accept failed: %s\n", strerror (errno));
+            }
           else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
             {
               log_error ("error allocating connection control data: %s\n",
@@ -1303,12 +1379,12 @@ handle_connections (int listen_fd)
           else
             {
               char threadname[50];
-	      npth_t thread;
+              npth_t thread;
 
               snprintf (threadname, sizeof threadname, "conn fd=%d", fd);
               ctrl->thread_startup.fd = INT2FD (fd);
               ret = npth_create (&thread, &tattr, start_connection_thread, ctrl);
-	      if (ret)
+              if (ret)
                 {
                   log_error ("error spawning connection handler: %s\n",
                              strerror (ret));
@@ -1316,10 +1392,19 @@ handle_connections (int listen_fd)
                   close (fd);
                 }
               else
-		npth_setname_np (thread, threadname);
+                npth_setname_np (thread, threadname);
             }
-          fd = -1;
-	}
+
+          ret--;
+        }
+
+#ifdef HAVE_LIBUSB
+      if (ret)
+        {
+          struct timeval tv = {0, 0};
+          libusb_handle_events_timeout_completed (NULL, &tv, NULL);
+        }
+#endif
     }
 
   cleanup ();
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index d0bc98e..9d92ff2 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -125,6 +125,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
 void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
 void scd_update_reader_status_file (void);
 void send_client_notifications (app_t app, int removal);
+void update_fdset_for_usb (int scanned, int all_have_intr_endp);
 
 
 #endif /*SCDAEMON_H*/

-----------------------------------------------------------------------

Summary of changes:
 scd/apdu.c        |  11 +++-
 scd/apdu.h        |   2 +-
 scd/app.c         |   6 ++-
 scd/ccid-driver.c |   8 ++-
 scd/ccid-driver.h |   2 +-
 scd/scdaemon.c    | 157 +++++++++++++++++++++++++++++++++++++++++-------------
 scd/scdaemon.h    |   1 +
 7 files changed, 145 insertions(+), 42 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list