1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-09 23:39:51 +02:00

scd: Fix card removal monitor.

* 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>
This commit is contained in:
NIIBE Yutaka 2016-12-30 13:17:49 +09:00
parent cdc8d0bd93
commit f300e12a79
3 changed files with 68 additions and 58 deletions

View File

@ -161,7 +161,7 @@ app_reset (app_t app, ctrl_t ctrl, int send_reset)
err = gpg_error (GPG_ERR_CARD_RESET); err = gpg_error (GPG_ERR_CARD_RESET);
/* Release the same application which is used by other sessions. */ /* Release the same application which is used by other sessions. */
send_client_notifications (app); send_client_notifications (app, 1);
} }
else else
{ {
@ -1035,7 +1035,7 @@ scd_update_reader_status_file (void)
if (a->card_status != status) if (a->card_status != status)
{ {
report_change (a->slot, 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) if (status == 0)
{ {

View 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. */ /* Helper to send the clients a status change notification. */
void void
send_client_notifications (app_t app) send_client_notifications (app_t app, int removal)
{ {
struct { struct {
pid_t pid; pid_t pid;
@ -1864,65 +1864,75 @@ send_client_notifications (app_t app)
struct server_local_s *sl; struct server_local_s *sl;
for (sl=session_list; sl; sl = sl->next_session) for (sl=session_list; sl; sl = sl->next_session)
{ if (sl->ctrl_backlink && sl->ctrl_backlink->app_ctx == app)
if (sl->event_signal && sl->assuan_ctx {
&& sl->ctrl_backlink->app_ctx == app) pid_t pid;
{
pid_t pid = assuan_get_pid (sl->assuan_ctx);
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
HANDLE handle = (void *)sl->event_signal; HANDLE handle;
#else
int signo;
#endif
for (kidx=0; kidx < killidx; kidx++) if (removal)
if (killed[kidx].pid == pid {
&& killed[kidx].handle == handle) sl->ctrl_backlink->app_ctx = NULL;
break; sl->card_removed = 1;
if (kidx < killidx) release_application (app);
log_info ("event %lx (%p) already triggered for client %d\n", }
if (!sl->event_signal || !sl->assuan_ctx)
continue;
pid = assuan_get_pid (sl->assuan_ctx);
#ifdef HAVE_W32_SYSTEM
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); sl->event_signal, handle, (int)pid);
else if (!SetEvent (handle))
{ log_error ("SetEvent(%lx) failed: %s\n",
log_info ("triggering event %lx (%p) for client %d\n", sl->event_signal, w32_strerror (-1));
sl->event_signal, handle, (int)pid); if (killidx < DIM (killed))
if (!SetEvent (handle)) {
log_error ("SetEvent(%lx) failed: %s\n", killed[killidx].pid = pid;
sl->event_signal, w32_strerror (-1)); killed[killidx].handle = handle;
if (killidx < DIM (killed)) killidx++;
{ }
killed[killidx].pid = pid; }
killed[killidx].handle = handle;
killidx++;
}
}
#else /*!HAVE_W32_SYSTEM*/ #else /*!HAVE_W32_SYSTEM*/
int signo = sl->event_signal; signo = sl->event_signal;
if (pid != (pid_t)(-1) && pid && signo > 0) if (pid != (pid_t)(-1) && pid && signo > 0)
{ {
for (kidx=0; kidx < killidx; kidx++) for (kidx=0; kidx < killidx; kidx++)
if (killed[kidx].pid == pid if (killed[kidx].pid == pid
&& killed[kidx].signo == signo) && killed[kidx].signo == signo)
break; break;
if (kidx < killidx) if (kidx < killidx)
log_info ("signal %d already sent to client %d\n", 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); signo, (int)pid);
else kill (pid, signo);
{ if (killidx < DIM (killed))
log_info ("sending signal %d to client %d\n", {
signo, (int)pid); killed[killidx].pid = pid;
kill (pid, signo); killed[killidx].signo = signo;
if (killidx < DIM (killed)) killidx++;
{ }
killed[killidx].pid = pid; }
killed[killidx].signo = signo; }
killidx++;
}
}
}
#endif /*!HAVE_W32_SYSTEM*/ #endif /*!HAVE_W32_SYSTEM*/
}
sl->ctrl_backlink->app_ctx = NULL;
sl->card_removed = 1;
release_application (app);
}
}
} }

View File

@ -124,7 +124,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
GPGRT_ATTR_SENTINEL(1); GPGRT_ATTR_SENTINEL(1);
void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args); void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
void scd_update_reader_status_file (void); 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*/ #endif /*SCDAEMON_H*/