[svn] GnuPG - r4905 - trunk/agent

svn author wk cvs at cvs.gnupg.org
Wed Dec 17 20:42:17 CET 2008


Author: wk
Date: 2008-12-17 20:42:17 +0100 (Wed, 17 Dec 2008)
New Revision: 4905

Modified:
   trunk/agent/ChangeLog
   trunk/agent/gpg-agent.c
Log:
Fix signal handling race condition.


Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog	2008-12-12 14:04:22 UTC (rev 4904)
+++ trunk/agent/ChangeLog	2008-12-17 19:42:17 UTC (rev 4905)
@@ -1,3 +1,8 @@
+2008-12-17  Werner Koch  <wk at g10code.com>
+
+	* gpg-agent.c (handle_connections): Set action of all pth event
+	handled signals to SIG_IGN.  Use a different pth_sigmask strategy.
+
 2008-12-10  Werner Koch  <wk at g10code.com>
 
 	* command.c (cmd_get_passphrase): Implement option --no-ask.

Modified: trunk/agent/gpg-agent.c
===================================================================
--- trunk/agent/gpg-agent.c	2008-12-12 14:04:22 UTC (rev 4904)
+++ trunk/agent/gpg-agent.c	2008-12-17 19:42:17 UTC (rev 4905)
@@ -1748,13 +1748,28 @@
 
 #ifndef HAVE_W32_SYSTEM /* fixme */
   /* Make sure that the signals we are going to handle are not blocked
-     and create an event object for them. */
+     and create an event object for them.  We also set the default
+     action to ignore because we use an Pth event to get notified
+     about signals.  This avoids that the default action is taken in
+     case soemthing goes wrong within Pth.  The problem might also be
+     a Pth bug.  */
   sigemptyset (&sigs );
-  sigaddset (&sigs, SIGHUP);
-  sigaddset (&sigs, SIGUSR1);
-  sigaddset (&sigs, SIGUSR2);
-  sigaddset (&sigs, SIGINT);
-  sigaddset (&sigs, SIGTERM);
+  {
+    static const int mysigs[] = { SIGHUP, SIGUSR1, SIGUSR2, SIGINT, SIGTERM };
+    struct sigaction sa;
+    int i;
+
+    for (i=0; i < DIM (mysigs); i++)
+      {
+        sigemptyset (&sa.sa_mask);
+        sa.sa_handler = SIG_IGN;
+        sa.sa_flags = 0;
+        sigaction (mysigs[i], &sa, NULL);
+        
+        sigaddset (&sigs, mysigs[i]);
+      }
+  }
+
   pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
   ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
 #else
@@ -1782,8 +1797,10 @@
 
   for (;;)
     {
-      sigset_t oldsigs;
+      /* Make sure that our signals are not blocked.  */
+      pth_sigmask (SIG_UNBLOCK, &sigs, NULL);
 
+      /* Shutdown test.  */
       if (shutdown_pending)
         {
           if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1)
@@ -1843,7 +1860,7 @@
           log_error (_("pth_select failed: %s - waiting 1s\n"),
                      strerror (errno));
           pth_sleep (1);
-	  continue;
+          continue;
 	}
 
       if (pth_event_occurred (ev))
@@ -1862,11 +1879,11 @@
           handle_tick ();
         }
 
-      
+
       /* We now might create new threads and because we don't want any
          signals (as we are handling them here) to be delivered to a
          new thread.  Thus we need to block those signals. */
-      pth_sigmask (SIG_BLOCK, &sigs, &oldsigs);
+      pth_sigmask (SIG_BLOCK, &sigs, NULL);
 
       if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset))
 	{
@@ -1943,10 +1960,6 @@
             }
           fd = GNUPG_INVALID_FD;
 	}
-
-      /* Restore the signal mask. */
-      pth_sigmask (SIG_SETMASK, &oldsigs, NULL);
-
     }
 
   pth_event_free (ev, PTH_FREE_ALL);




More information about the Gnupg-commits mailing list