From 80a641ec0d1a9a8ee8728c0680cea06579dd79ce Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Tue, 30 Aug 2016 19:10:22 -0400 Subject: [PATCH] Fix cancellation of gpgme without pthread_cancel. --- src/commands.c | 16 +++++++--------- src/common.h | 12 ++++++++++++ src/crypto.c | 4 ++++ src/pwmd.c | 35 ++++++----------------------------- 4 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/commands.c b/src/commands.c index dfa33e5f..b873d376 100644 --- a/src/commands.c +++ b/src/commands.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "pwmd-error.h" #include @@ -4291,10 +4292,9 @@ kill_command (assuan_context_t ctx, char *line) if (!rc) { #ifdef HAVE_PTHREAD_CANCEL - rc = pthread_cancel (thd->tid); + pthread_cancel (thd->tid); #else - close (thd->fd); - thd->fd = -1; + pthread_kill (thd->tid, SIGUSR2); #endif break; } @@ -4312,10 +4312,9 @@ kill_command (assuan_context_t ctx, char *line) if (!strcmp (client->thd->tls->fp, thd->tls->fp)) { #ifdef HAVE_PTHREAD_CANCEL - rc = pthread_cancel (thd->tid); + pthread_cancel (thd->tid); #else - close (thd->fd); - thd->fd = -1; + pthread_kill (thd->tid, SIGUSR2); #endif break; } @@ -4326,10 +4325,9 @@ kill_command (assuan_context_t ctx, char *line) if (client->thd->peer->uid == thd->peer->uid) { #ifdef HAVE_PTHREAD_CANCEL - rc = pthread_cancel (thd->tid); + pthread_cancel (thd->tid); #else - close (thd->fd); - thd->fd = -1; + pthread_kill (thd->tid, SIGUSR2); #endif } } diff --git a/src/common.h b/src/common.h index 5da4a943..abab9a64 100644 --- a/src/common.h +++ b/src/common.h @@ -64,6 +64,18 @@ #define CLIENT_STATE_COMMAND 3 #define CLIENT_STATE_DISCON 4 +#ifndef HAVE_PTHREAD_CANCEL +pthread_key_t signal_thread_key; +#define TEST_CANCEL() do { \ + int *cancel = (int *) pthread_getspecific (signal_thread_key); \ + if (cancel && *cancel) \ + pthread_exit (NULL); \ + } while (0) +#else +#define TEST_CANCEL() +#endif + + struct client_thread_s { pthread_t tid; diff --git a/src/crypto.c b/src/crypto.c index 9064eb08..d1aa60c3 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -552,6 +552,7 @@ crypto_decrypt (struct client_s *client, struct crypto_s *crypto) if (rc) break; + TEST_CANCEL (); } while (!gpgme_wait (crypto->ctx, &rc, 0) && !rc); } @@ -823,6 +824,7 @@ crypto_encrypt (struct client_s *client, struct crypto_s *crypto) if (rc) break; + TEST_CANCEL(); } while (!gpgme_wait (crypto->ctx, &rc, 0) && !rc); if (!rc) @@ -964,6 +966,7 @@ crypto_passwd (struct client_s *client, struct crypto_s *crypto) if (rc) break; + TEST_CANCEL(); } while (!gpgme_wait (crypto->ctx, &rc, 0) && !rc); } @@ -1002,6 +1005,7 @@ crypto_genkey (struct client_s *client, struct crypto_s *crypto, if (rc) break; + TEST_CANCEL(); } while (!gpgme_wait (crypto->ctx, &rc, 0) && !rc); if (!rc) diff --git a/src/pwmd.c b/src/pwmd.c index 03c9650a..7e564b11 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -102,10 +102,6 @@ static pthread_mutex_t quit_mutex; static int log_fd; static unsigned assuan_level; -#ifndef HAVE_PTHREAD_CANCEL -static pthread_key_t signal_thread_key; -#endif - pthread_t accept_tid; #ifdef WITH_GNUTLS static int tls_fd; @@ -118,6 +114,9 @@ static int signal_loop (sigset_t sigset); #ifndef HAVE_PTHREAD_CANCEL #define INIT_SIGNAL(s, cb) do { \ + int *n = xmalloc (sizeof (int)); \ + *n = 0; \ + pthread_setspecific (signal_thread_key, n); \ struct sigaction act; \ sigset_t sigset; \ sigemptyset (&sigset); \ @@ -129,14 +128,6 @@ static int signal_loop (sigset_t sigset); act.sa_sigaction = cb; \ sigaction (s, &act, NULL); \ } while (0) - -#define TEST_CANCEL() do { \ - int *cancel = (int *) pthread_getspecific (signal_thread_key); \ - if (cancel && *cancel) \ - pthread_exit (NULL); \ - } while (0) -#else -#define TEST_CANCEL() #endif #ifndef HAVE_PTHREAD_CANCEL @@ -146,7 +137,6 @@ catch_thread_signal (int sig, siginfo_t *info, void *ctx) int *n = (int *) pthread_getspecific (signal_thread_key); *n = 1; - pthread_setspecific (signal_thread_key, n); } #endif @@ -193,10 +183,6 @@ static void * reload_rcfile_thread (void *arg) { #ifndef HAVE_PTHREAD_CANCEL - int *n = xmalloc (sizeof (int)); - - *n = 0; - pthread_setspecific (signal_thread_key, n); INIT_SIGNAL (SIGUSR2, catch_thread_signal); #endif @@ -1084,6 +1070,9 @@ client_thread (void *data) { struct client_thread_s *thd = data; struct client_s *cl = xcalloc (1, sizeof (struct client_s)); +#ifndef HAVE_PTHREAD_CANCEL + INIT_SIGNAL (SIGUSR2, catch_thread_signal); +#endif #ifdef HAVE_PR_SET_NAME prctl (PR_SET_NAME, "client"); @@ -1758,10 +1747,6 @@ accept_thread (void *arg) { int sockfd = *(int *) arg; #ifndef HAVE_PTHREAD_CANCEL - int *n = xmalloc (sizeof (int)); - - *n = 0; - pthread_setspecific (signal_thread_key, n); INIT_SIGNAL (SIGUSR2, catch_thread_signal); fcntl (sockfd, F_SETFL, O_NONBLOCK); #endif @@ -1856,10 +1841,6 @@ cache_timer_thread (void *arg) { unsigned k = 0; #ifndef HAVE_PTHREAD_CANCEL - int *n = xmalloc (sizeof (int)); - - *n = 0; - pthread_setspecific (signal_thread_key, n); INIT_SIGNAL (SIGUSR2, catch_thread_signal); #endif @@ -1941,10 +1922,6 @@ waiting_for_exit (void *arg) { int last = 0; #ifndef HAVE_PTHREAD_CANCEL - int *n = xmalloc (sizeof (int)); - - *n = 0; - pthread_setspecific (signal_thread_key, n); INIT_SIGNAL (SIGUSR2, catch_thread_signal); #endif -- 2.11.4.GIT