[Pkg-gnupg-commit] [gnupg2] 13/124: scd: Fix scd_kick_the_loop.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Apr 5 15:55:28 UTC 2017


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch experimental
in repository gnupg2.

commit f9acc7d18bb90f47dafe7e32ae92f567756d6b12
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Fri Mar 3 20:30:56 2017 +0900

    scd: Fix scd_kick_the_loop.
    
    * scd/scdaemon.c (notify_fd): Remove.
    (the_event) [W32]: New.
    (main_thread_pid) [!W32]: New.
    (handle_signal): Handle SIGCONT.
    (scd_kick_the_loop): Use signal on UNIX and event on Windows.
    (handle_connections): Likewise.
    --
    
    Code with CreateEvent is copied from gpg-agent.c.
    Code for signal is copied from dkg's gpg-agent-idling in Debian.
    
    GnuPG-bug-id: 2982
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
---
 scd/scdaemon.c | 87 +++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 31 deletions(-)

diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index f7e9f83..4b63c9b 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -224,8 +224,12 @@ static char *redir_socket_name;
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
 
-/* FD to notify update of usb devices.  */
-static int notify_fd;
+#ifdef HAVE_W32_SYSTEM
+static HANDLE the_event;
+#else
+/* PID to notify update of usb devices.  */
+static pid_t main_thread_pid;
+#endif
 

 static char *create_socket_name (char *standard_name);
 static gnupg_fd_t create_server_socket (const char *name,
@@ -996,6 +1000,10 @@ handle_signal (int signo)
       log_info ("SIGUSR2 received - no action defined\n");
       break;
 
+    case SIGCONT:
+      /* Nothing.  */
+      break;
+
     case SIGTERM:
       if (!shutdown_pending)
         log_info ("SIGTERM received - shutting down ...\n");
@@ -1185,8 +1193,17 @@ scd_kick_the_loop (void)
   int ret;
 
   /* Kick the select loop.  */
-  ret = write (notify_fd, "", 1);
-  (void)ret;
+#ifdef HAVE_W32_SYSTEM
+  ret = SetEvent (the_event);
+  if (ret == 0)
+    log_error ("SetEvent for scd_kick_the_loop failed: %s\n",
+               w32_strerror (-1));
+#else
+  ret = kill (main_thread_pid, SIGCONT);
+  if (ret < 0)
+    log_error ("SetEvent for scd_kick_the_loop failed: %s\n",
+               gpg_strerror (gpg_error_from_syserror ()));
+#endif
 }
 
 /* Connection handler loop.  Wait for connection requests and spawn a
@@ -1206,18 +1223,12 @@ handle_connections (int listen_fd)
   struct timespec timeout;
   struct timespec *t;
   int saved_errno;
-#ifndef HAVE_W32_SYSTEM
+#ifdef HAVE_W32_SYSTEM
+  HANDLE events[2];
+  unsigned int events_set;
+#else
   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);
   if (ret)
@@ -1228,14 +1239,40 @@ handle_connections (int listen_fd)
 
   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
 
-#ifndef HAVE_W32_SYSTEM
+#ifdef HAVE_W32_SYSTEM
+  {
+    HANDLE h, h2;
+    SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
+
+    events[0] = the_event = INVALID_HANDLE_VALUE;
+    events[1] = INVALID_HANDLE_VALUE;
+    h = CreateEvent (&sa, TRUE, FALSE, NULL);
+    if (!h)
+      log_error ("can't create scd event: %s\n", w32_strerror (-1) );
+    else if (!DuplicateHandle (GetCurrentProcess(), h,
+                               GetCurrentProcess(), &h2,
+                               EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0))
+      {
+        log_error ("setting synchronize for scd_kick_the_loop failed: %s\n",
+                   w32_strerror (-1) );
+        CloseHandle (h);
+      }
+    else
+      {
+        CloseHandle (h);
+        events[0] = the_event = h2;
+      }
+  }
+#else
   npth_sigev_init ();
   npth_sigev_add (SIGHUP);
   npth_sigev_add (SIGUSR1);
   npth_sigev_add (SIGUSR2);
   npth_sigev_add (SIGINT);
+  npth_sigev_add (SIGCONT);
   npth_sigev_add (SIGTERM);
   npth_sigev_fini ();
+  main_thread_pid = getpid ();
 #endif
 
   FD_ZERO (&fdset);
@@ -1246,10 +1283,6 @@ handle_connections (int listen_fd)
       nfd = listen_fd;
     }
 
-  FD_SET (pipe_fd[0], &fdset);
-  if (nfd < pipe_fd[0])
-    nfd = pipe_fd[0];
-
   for (;;)
     {
       int periodical_check;
@@ -1264,8 +1297,6 @@ handle_connections (int listen_fd)
              file descriptors to wait for, so that the select will be
              used to just wait on a signal or timeout event. */
           FD_ZERO (&fdset);
-          FD_SET (pipe_fd[0], &fdset);
-          nfd = pipe_fd[0];
           listen_fd = -1;
         }
 
@@ -1291,8 +1322,11 @@ handle_connections (int listen_fd)
       while (npth_sigev_get_pending(&signo))
         handle_signal (signo);
 #else
-      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, t, NULL, NULL);
+      ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, t,
+                          events, &events_set);
       saved_errno = errno;
+      if (events_set & 1)
+        continue;
 #endif
 
       if (ret == -1 && saved_errno != EINTR)
@@ -1307,13 +1341,6 @@ 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;
@@ -1351,8 +1378,6 @@ 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);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list