scd: Fix card removal monitor.
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 30 Dec 2016 04:17:49 +0000 (13:17 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 30 Dec 2016 04:17:49 +0000 (13:17 +0900)
* scd/app.c (app_reset): Call send_client_notification with REMOVAL.
(scd_update_reader_status_file): Likewise.
* scd/command.c (send_client_notifications): Distinguish removal.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
scd/app.c
scd/command.c
scd/scdaemon.h

index fa05475..39910d2 100644 (file)
--- a/scd/app.c
+++ b/scd/app.c
@@ -161,7 +161,7 @@ app_reset (app_t app, ctrl_t ctrl, int send_reset)
         err = gpg_error (GPG_ERR_CARD_RESET);
 
       /* Release the same application which is used by other sessions.  */
-      send_client_notifications (app);
+      send_client_notifications (app, 1);
     }
   else
     {
@@ -1035,7 +1035,7 @@ scd_update_reader_status_file (void)
           if (a->card_status != status)
             {
               report_change (a->slot, a->card_status, status);
-              send_client_notifications (a);
+              send_client_notifications (a, status == 0);
 
               if (status == 0)
                 {
index 0c823d2..ce2be34 100644 (file)
@@ -1849,7 +1849,7 @@ send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
 
 /* Helper to send the clients a status change notification.  */
 void
-send_client_notifications (app_t app)
+send_client_notifications (app_t app, int removal)
 {
   struct {
     pid_t pid;
@@ -1864,65 +1864,75 @@ send_client_notifications (app_t app)
   struct server_local_s *sl;
 
   for (sl=session_list; sl; sl = sl->next_session)
-    {
-      if (sl->event_signal && sl->assuan_ctx
-          && sl->ctrl_backlink->app_ctx == app)
-        {
-          pid_t pid = assuan_get_pid (sl->assuan_ctx);
+    if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app)
+      {
+        pid_t pid;
+#ifdef HAVE_W32_SYSTEM
+        HANDLE handle;
+#else
+        int signo;
+#endif
+
+        if (removal)
+          {
+            sl->ctrl_backlink->app_ctx = NULL;
+            sl->card_removed = 1;
+            release_application (app);
+          }
+
+        if (!sl->event_signal || !sl->assuan_ctx)
+          continue;
+
+        pid = assuan_get_pid (sl->assuan_ctx);
+
 #ifdef HAVE_W32_SYSTEM
-          HANDLE handle = (void *)sl->event_signal;
-
-          for (kidx=0; kidx < killidx; kidx++)
-            if (killed[kidx].pid == pid
-                && killed[kidx].handle == handle)
-              break;
-          if (kidx < killidx)
-            log_info ("event %lx (%p) already triggered for client %d\n",
+        handle = (void *)sl->event_signal;
+        for (kidx=0; kidx < killidx; kidx++)
+          if (killed[kidx].pid == pid
+              && killed[kidx].handle == handle)
+            break;
+        if (kidx < killidx)
+          log_info ("event %lx (%p) already triggered for client %d\n",
+                    sl->event_signal, handle, (int)pid);
+        else
+          {
+            log_info ("triggering event %lx (%p) for client %d\n",
                       sl->event_signal, handle, (int)pid);
-          else
-            {
-              log_info ("triggering event %lx (%p) for client %d\n",
-                        sl->event_signal, handle, (int)pid);
-              if (!SetEvent (handle))
-                log_error ("SetEvent(%lx) failed: %s\n",
-                           sl->event_signal, w32_strerror (-1));
-              if (killidx < DIM (killed))
-                {
-                  killed[killidx].pid = pid;
-                  killed[killidx].handle = handle;
-                  killidx++;
-                }
-            }
+            if (!SetEvent (handle))
+              log_error ("SetEvent(%lx) failed: %s\n",
+                         sl->event_signal, w32_strerror (-1));
+            if (killidx < DIM (killed))
+              {
+                killed[killidx].pid = pid;
+                killed[killidx].handle = handle;
+                killidx++;
+              }
+          }
 #else /*!HAVE_W32_SYSTEM*/
-          int signo = sl->event_signal;
-
-          if (pid != (pid_t)(-1) && pid && signo > 0)
-            {
-              for (kidx=0; kidx < killidx; kidx++)
-                if (killed[kidx].pid == pid
-                    && killed[kidx].signo == signo)
-                  break;
-              if (kidx < killidx)
-                log_info ("signal %d already sent to client %d\n",
+        signo = sl->event_signal;
+
+        if (pid != (pid_t)(-1) && pid && signo > 0)
+          {
+            for (kidx=0; kidx < killidx; kidx++)
+              if (killed[kidx].pid == pid
+                  && killed[kidx].signo == signo)
+                break;
+            if (kidx < killidx)
+              log_info ("signal %d already sent to client %d\n",
+                        signo, (int)pid);
+            else
+              {
+                log_info ("sending signal %d to client %d\n",
                           signo, (int)pid);
-              else
-                {
-                  log_info ("sending signal %d to client %d\n",
-                            signo, (int)pid);
-                  kill (pid, signo);
-                  if (killidx < DIM (killed))
-                    {
-                      killed[killidx].pid = pid;
-                      killed[killidx].signo = signo;
-                      killidx++;
-                    }
-                }
-            }
+                kill (pid, signo);
+                if (killidx < DIM (killed))
+                  {
+                    killed[killidx].pid = pid;
+                    killed[killidx].signo = signo;
+                    killidx++;
+                  }
+              }
+          }
 #endif /*!HAVE_W32_SYSTEM*/
-
-          sl->ctrl_backlink->app_ctx = NULL;
-          sl->card_removed = 1;
-          release_application (app);
-        }
-    }
+      }
 }
index 22b17b4..d0bc98e 100644 (file)
@@ -124,7 +124,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
      GPGRT_ATTR_SENTINEL(1);
 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);
+void send_client_notifications (app_t app, int removal);
 
 
 #endif /*SCDAEMON_H*/