diff options
Diffstat (limited to 'agent')
-rw-r--r-- | agent/Makefile.am | 4 | ||||
-rw-r--r-- | agent/cache.c | 52 | ||||
-rw-r--r-- | agent/call-pinentry.c | 108 | ||||
-rw-r--r-- | agent/call-scd.c | 64 | ||||
-rw-r--r-- | agent/findkey.c | 4 | ||||
-rw-r--r-- | agent/gpg-agent.c | 310 | ||||
-rw-r--r-- | agent/trustlist.c | 24 |
7 files changed, 236 insertions, 330 deletions
diff --git a/agent/Makefile.am b/agent/Makefile.am index 00b7d43c9..c9fa9c7e8 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -72,9 +72,9 @@ gpg_agent_res_deps = #endif -gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) +gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) gpg_agent_LDADD = $(commonpth_libs) \ - $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpg_agent_LDFLAGS = $(extra_bin_ldflags) $(gpg_agent_res_ldflags) gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps) diff --git a/agent/cache.c b/agent/cache.c index 9c20469d2..9b90d93f4 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -24,7 +24,7 @@ #include <string.h> #include <time.h> #include <assert.h> -#include <pth.h> +#include <npth.h> #include "agent.h" @@ -33,7 +33,7 @@ /* A mutex used to protect the encryption. This is required because we use one context to do all encryption and decryption. */ -static pth_mutex_t encryption_lock; +static npth_mutex_t encryption_lock; /* The encryption context. This is the only place where the encryption key for all cached entries is available. It would be nice to keep this (or just the key) in some hardware device, for example @@ -71,11 +71,12 @@ static ITEM thecache; void initialize_module_cache (void) { - if (!pth_mutex_init (&encryption_lock)) - { - gpg_error_t err = gpg_error_from_syserror (); - log_fatal ("error initializing cache module: %s\n", gpg_strerror (err)); - } + int err; + + err = npth_mutex_init (&encryption_lock, NULL); + + if (err) + log_fatal ("error initializing cache module: %s\n", strerror (err)); } @@ -98,12 +99,14 @@ init_encryption (void) { gpg_error_t err; void *key; + int res; if (encryption_handle) return 0; /* Shortcut - Already initialized. */ - if (!pth_mutex_acquire (&encryption_lock, 0, NULL)) - log_fatal ("failed to acquire cache encryption mutex\n"); + res = npth_mutex_lock (&encryption_lock); + if (res) + log_fatal ("failed to acquire cache encryption mutex: %s\n", strerror (res)); err = gcry_cipher_open (&encryption_handle, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_AESWRAP, GCRY_CIPHER_SECURE); @@ -127,8 +130,9 @@ init_encryption (void) log_error ("error initializing cache encryption context: %s\n", gpg_strerror (err)); - if (!pth_mutex_release (&encryption_lock)) - log_fatal ("failed to release cache encryption mutex\n"); + res = npth_mutex_unlock (&encryption_lock); + if (res) + log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res)); return err? gpg_error (GPG_ERR_NOT_INITIALIZED) : 0; } @@ -148,6 +152,7 @@ new_data (const char *string, struct secret_data_s **r_data) struct secret_data_s *d, *d_enc; size_t length; int total; + int res; *r_data = NULL; @@ -178,13 +183,17 @@ new_data (const char *string, struct secret_data_s **r_data) } d_enc->totallen = total; - if (!pth_mutex_acquire (&encryption_lock, 0, NULL)) - log_fatal ("failed to acquire cache encryption mutex\n"); + res = npth_mutex_lock (&encryption_lock); + if (res) + log_fatal ("failed to acquire cache encryption mutex: %s\n", + strerror (res)); + err = gcry_cipher_encrypt (encryption_handle, d_enc->data, total, d->data, total - 8); xfree (d); - if (!pth_mutex_release (&encryption_lock)) - log_fatal ("failed to release cache encryption mutex\n"); + res = npth_mutex_unlock (&encryption_lock); + if (res) + log_fatal ("failed to release cache encryption mutex: %s\n", strerror (res)); if (err) { xfree (d_enc); @@ -378,6 +387,7 @@ agent_get_cache (const char *key, cache_mode_t cache_mode) gpg_error_t err; ITEM r; char *value = NULL; + int res; if (cache_mode == CACHE_MODE_IGNORE) return NULL; @@ -405,13 +415,17 @@ agent_get_cache (const char *key, cache_mode_t cache_mode) err = gpg_error_from_syserror (); else { - if (!pth_mutex_acquire (&encryption_lock, 0, NULL)) - log_fatal ("failed to acquire cache encryption mutex\n"); + res = npth_mutex_lock (&encryption_lock); + if (res) + log_fatal ("failed to acquire cache encryption mutex: %s\n", + strerror (res)); err = gcry_cipher_decrypt (encryption_handle, value, r->pw->totallen - 8, r->pw->data, r->pw->totallen); - if (!pth_mutex_release (&encryption_lock)) - log_fatal ("failed to release cache encryption mutex\n"); + res = npth_mutex_unlock (&encryption_lock); + if (res) + log_fatal ("failed to release cache encryption mutex: %s\n", + strerror (res)); } if (err) { diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 36093bb8b..34ab3840e 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -32,7 +32,7 @@ # include <sys/types.h> # include <signal.h> #endif -#include <pth.h> +#include <npth.h> #include "agent.h" #include <assuan.h> @@ -62,10 +62,10 @@ static assuan_context_t entry_ctx; static ctrl_t entry_owner; /* A mutex used to serialize access to the pinentry. */ -static pth_mutex_t entry_lock; +static npth_mutex_t entry_lock; /* The thread ID of the popup working thread. */ -static pth_t popup_tid; +static npth_t popup_tid; /* A flag used in communication between the popup working thread and its stop function. */ @@ -95,39 +95,19 @@ initialize_module_call_pinentry (void) if (!initialized) { - if (pth_mutex_init (&entry_lock)) + if (npth_mutex_init (&entry_lock, NULL)) initialized = 1; } } -static void -dump_mutex_state (pth_mutex_t *m) -{ -#ifdef _W32_PTH_H - (void)m; - log_printf ("unknown under W32"); -#else - if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) - log_printf ("not_initialized"); - else if (!(m->mx_state & PTH_MUTEX_LOCKED)) - log_printf ("not_locked"); - else - log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count); -#endif -} - - /* This function may be called to print infromation pertaining to the current state of this module to the log. */ void agent_query_dump_state (void) { - log_info ("agent_query_dump_state: entry_lock="); - dump_mutex_state (&entry_lock); - log_printf ("\n"); - log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n", + log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%lx\n", entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid); } @@ -151,13 +131,15 @@ static int unlock_pinentry (int rc) { assuan_context_t ctx = entry_ctx; + int err; entry_ctx = NULL; - if (!pth_mutex_release (&entry_lock)) + err = npth_mutex_unlock (&entry_lock); + if (err) { - log_error ("failed to release the entry lock\n"); + log_error ("failed to release the entry lock: %s\n", strerror (err)); if (!rc) - rc = gpg_error (GPG_ERR_INTERNAL); + rc = gpg_error_from_errno (err); } assuan_release (ctx); return rc; @@ -222,30 +204,31 @@ getinfo_pid_cb (void *opaque, const void *buffer, size_t length) static int start_pinentry (ctrl_t ctrl) { - int rc; + int rc = 0; const char *pgmname; assuan_context_t ctx; const char *argv[5]; int no_close_list[3]; int i; - pth_event_t evt; const char *tmpstr; unsigned long pinentry_pid; const char *value; + struct timespec abstime; + int err; - evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); - if (!pth_mutex_acquire (&entry_lock, 0, evt)) + npth_clock_gettime (&abstime); + abstime.tv_sec += LOCK_TIMEOUT; + err = npth_mutex_timedlock (&entry_lock, &abstime); + if (err) { - if (pth_event_occurred (evt)) - rc = gpg_error (GPG_ERR_TIMEOUT); + if (err == ETIMEDOUT) + rc = gpg_error (GPG_ERR_TIMEOUT); else - rc = gpg_error (GPG_ERR_INTERNAL); - pth_event_free (evt, PTH_FREE_THIS); + rc = gpg_error_from_errno (rc); log_error (_("failed to acquire the pinentry lock: %s\n"), gpg_strerror (rc)); return rc; } - pth_event_free (evt, PTH_FREE_THIS); entry_owner = ctrl; @@ -484,33 +467,37 @@ start_pinentry (ctrl_t ctrl) int pinentry_active_p (ctrl_t ctrl, int waitseconds) { + int err; (void)ctrl; if (waitseconds > 0) { - pth_event_t evt; + struct timespec abstime; int rc; - evt = pth_event (PTH_EVENT_TIME, pth_timeout (waitseconds, 0)); - if (!pth_mutex_acquire (&entry_lock, 0, evt)) + npth_clock_gettime (&abstime); + abstime.tv_sec += waitseconds; + err = npth_mutex_timedlock (&entry_lock, &abstime); + if (err) { - if (pth_event_occurred (evt)) + if (err == ETIMEDOUT) rc = gpg_error (GPG_ERR_TIMEOUT); else rc = gpg_error (GPG_ERR_INTERNAL); - pth_event_free (evt, PTH_FREE_THIS); return rc; } - pth_event_free (evt, PTH_FREE_THIS); } else { - if (!pth_mutex_acquire (&entry_lock, 1, NULL)) + err = npth_mutex_trylock (&entry_lock); + if (err) return gpg_error (GPG_ERR_LOCKED); } - if (!pth_mutex_release (&entry_lock)) - log_error ("failed to release the entry lock at %d\n", __LINE__); + err = npth_mutex_unlock (&entry_lock); + if (err) + log_error ("failed to release the entry lock at %d: %s\n", __LINE__, + strerror (errno)); return 0; } @@ -1185,7 +1172,8 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn) { int rc; char line[ASSUAN_LINELENGTH]; - pth_attr_t tattr; + npth_attr_t tattr; + int err; if (ctrl->pinentry_mode != PINENTRY_MODE_ASK) return gpg_error (GPG_ERR_CANCELED); @@ -1212,22 +1200,22 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn) return unlock_pinentry (rc); } - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message"); + err = npth_attr_init (&tattr); + if (err) + return unlock_pinentry (gpg_error_from_errno (err)); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); popup_finished = 0; - popup_tid = pth_spawn (tattr, popup_message_thread, NULL); - if (!popup_tid) + err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL); + npth_attr_destroy (&tattr); + if (err) { - rc = gpg_error_from_syserror (); + rc = gpg_error_from_errno (err); log_error ("error spawning popup message handler: %s\n", - strerror (errno) ); - pth_attr_destroy (tattr); + strerror (err) ); return unlock_pinentry (rc); } - pth_attr_destroy (tattr); + npth_setname_np (popup_tid, "popup-message"); return 0; } @@ -1277,11 +1265,13 @@ agent_popup_message_stop (ctrl_t ctrl) #endif /* Now wait for the thread to terminate. */ - rc = pth_join (popup_tid, NULL); + rc = npth_join (popup_tid, NULL); if (!rc) log_debug ("agent_popup_message_stop: pth_join failed: %s\n", strerror (errno)); - popup_tid = NULL; + /* Thread IDs are opaque, but we try our best here by resetting it + to the same content that a static global variable has. */ + memset (&popup_tid, '\0', sizeof (popup_tid)); entry_owner = NULL; /* Now we can close the connection. */ diff --git a/agent/call-scd.c b/agent/call-scd.c index 9a6884bd2..ccdb637d4 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -34,7 +34,7 @@ #ifndef HAVE_W32_SYSTEM #include <sys/wait.h> #endif -#include <pth.h> +#include <npth.h> #include "agent.h" #include <assuan.h> @@ -93,7 +93,7 @@ struct inq_needpin_s static struct scd_local_s *scd_local_list; /* A Mutex used inside the start_scd function. */ -static pth_mutex_t start_scd_lock; +static npth_mutex_t start_scd_lock; /* A malloced string with the name of the socket to be used for additional connections. May be NULL if not provided by @@ -120,47 +120,29 @@ static gpg_error_t membuf_data_cb (void *opaque, /* This function must be called once to initialize this module. This has to be done before a second thread is spawned. We can't do the - static initialization because Pth emulation code might not be able + static initialization because NPth emulation code might not be able to do a static init; in particular, it is not possible for W32. */ void initialize_module_call_scd (void) { static int initialized; + int err; if (!initialized) { - if (!pth_mutex_init (&start_scd_lock)) - log_fatal ("error initializing mutex: %s\n", strerror (errno)); + err = npth_mutex_init (&start_scd_lock, NULL); + if (err) + log_fatal ("error initializing mutex: %s\n", strerror (err)); initialized = 1; } } -static void -dump_mutex_state (pth_mutex_t *m) -{ -#ifdef _W32_PTH_H - (void)m; - log_printf ("unknown under W32"); -#else - if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) - log_printf ("not_initialized"); - else if (!(m->mx_state & PTH_MUTEX_LOCKED)) - log_printf ("not_locked"); - else - log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count); -#endif -} - - /* This function may be called to print infromation pertaining to the current state of this module to the log. */ void agent_scd_dump_state (void) { - log_info ("agent_scd_dump_state: scd_lock="); - dump_mutex_state (&start_scd_lock); - log_printf ("\n"); log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n", primary_scd_ctx, (long)assuan_get_pid (primary_scd_ctx), @@ -253,10 +235,11 @@ start_scd (ctrl_t ctrl) /* We need to protect the following code. */ - if (!pth_mutex_acquire (&start_scd_lock, 0, NULL)) + rc = npth_mutex_lock (&start_scd_lock); + if (rc) { log_error ("failed to acquire the start_scd lock: %s\n", - strerror (errno)); + strerror (rc)); return gpg_error (GPG_ERR_INTERNAL); } @@ -420,8 +403,9 @@ start_scd (ctrl_t ctrl) { ctrl->scd_local->ctx = ctx; } - if (!pth_mutex_release (&start_scd_lock)) - log_error ("failed to release the start_scd lock: %s\n", strerror (errno)); + rc = npth_mutex_unlock (&start_scd_lock); + if (rc) + log_error ("failed to release the start_scd lock: %s\n", strerror (rc)); return err; } @@ -440,35 +424,36 @@ agent_scd_check_running (void) void agent_scd_check_aliveness (void) { - pth_event_t evt; pid_t pid; #ifdef HAVE_W32_SYSTEM DWORD rc; #else int rc; #endif + struct timespec abstime; + int err; if (!primary_scd_ctx) return; /* No scdaemon running. */ /* This is not a critical function so we use a short timeout while acquiring the lock. */ - evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0)); - if (!pth_mutex_acquire (&start_scd_lock, 0, evt)) + npth_clock_gettime (&abstime); + abstime.tv_sec += 1; + err = npth_mutex_timedlock (&start_scd_lock, &abstime); + if (err) { - if (pth_event_occurred (evt)) + if (err == ETIMEDOUT) { if (opt.verbose > 1) log_info ("failed to acquire the start_scd lock while" - " doing an aliveness check: %s\n", "timeout"); + " doing an aliveness check: %s\n", strerror (err)); } else log_error ("failed to acquire the start_scd lock while" - " doing an aliveness check: %s\n", strerror (errno)); - pth_event_free (evt, PTH_FREE_THIS); + " doing an aliveness check: %s\n", strerror (err)); return; } - pth_event_free (evt, PTH_FREE_THIS); if (primary_scd_ctx) { @@ -513,9 +498,10 @@ agent_scd_check_aliveness (void) } } - if (!pth_mutex_release (&start_scd_lock)) + err = npth_mutex_unlock (&start_scd_lock); + if (err) log_error ("failed to release the start_scd lock while" - " doing the aliveness check: %s\n", strerror (errno)); + " doing the aliveness check: %s\n", strerror (err)); } diff --git a/agent/findkey.c b/agent/findkey.c index 11b3cca4d..a03d0c423 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -29,7 +29,7 @@ #include <unistd.h> #include <sys/stat.h> #include <assert.h> -#include <pth.h> /* (we use pth_sleep) */ +#include <npth.h> /* (we use pth_sleep) */ #include "agent.h" #include "i18n.h" @@ -382,7 +382,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, { /* We need to give the other thread a chance to actually put it into the cache. */ - pth_sleep (1); + npth_sleep (1); goto retry; } /* Timeout - better call pinentry now the plain way. */ diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index c264ba3c3..d6c4f3463 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -38,7 +38,7 @@ #ifdef HAVE_SIGNAL_H # include <signal.h> #endif -#include <pth.h> +#include <npth.h> #define JNLIB_NEED_LOG_LOGV #define JNLIB_NEED_AFLOCAL @@ -268,6 +268,9 @@ static char *current_logfile; watched. */ static pid_t parent_pid = (pid_t)(-1); +/* Number of active connections. */ +static int active_connections; + /* Local prototypes. @@ -287,29 +290,7 @@ static void check_own_socket (void); static int check_for_running_agent (int silent, int mode); /* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_PTH_IMPL; - -#if defined(GCRY_THREAD_OPTION_VERSION) && (GCRY_THREAD_OPTION_VERSION == 0) -#define USE_GCRY_THREAD_CBS 1 -#endif - -#ifdef USE_GCRY_THREAD_CBS -GCRY_THREAD_OPTION_PTH_IMPL; - -static int fixed_gcry_pth_init (void) -{ - return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; -} -#endif - - -#ifndef PTH_HAVE_PTH_THREAD_ID -static unsigned long pth_thread_id (void) -{ - return (unsigned long)pth_self (); -} -#endif - +ASSUAN_SYSTEM_NPTH_IMPL; /* @@ -624,19 +605,7 @@ main (int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - -#ifdef USE_GCRY_THREAD_CBS - /* Libgcrypt requires us to register the threading model first. - Note that this will also do the pth_init. */ - gcry_threads_pth.init = fixed_gcry_pth_init; - err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); - if (err) - { - log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", - gpg_strerror (err)); - } -#endif - + npth_init (); /* Check that the libraries are suitable. Do it here because the option parsing may need services of the library. */ @@ -651,7 +620,7 @@ main (int argc, char **argv ) malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug); @@ -1091,19 +1060,9 @@ main (int argc, char **argv ) /* Close the socket FD. */ close (fd); - /* Note that we used a standard fork so that Pth runs in - both the parent and the child. The pth_fork would - terminate Pth in the child but that is not the way we - want it. Thus we use a plain fork and terminate Pth here - in the parent. The pth_kill may or may not work reliable - but it should not harm to call it. Because Pth fiddles - with the signal mask the signal mask might not be correct - right now and thus we restore it. That is not strictly - necessary but some programs falsely assume a cleared - signal mask. */ -#warning need to do something about pth_kill - see bug#1320 - if ( !pth_kill () ) - log_error ("pth_kill failed in forked process\n"); + /* The signal mask might not be correct right now and thus + we restore it. That is not strictly necessary but some + programs falsely assume a cleared signal mask. */ #ifdef HAVE_SIGPROCMASK if (startup_signal_mask_valid) @@ -1432,9 +1391,9 @@ get_agent_ssh_socket_name (void) void * get_agent_scd_notify_event (void) { - static HANDLE the_event; + static HANDLE the_event = INVALID_HANDLE_VALUE; - if (!the_event) + if (the_event == INVALID_HANDLE_VALUE) { HANDLE h, h2; SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; @@ -1758,6 +1717,7 @@ agent_sigusr2_action (void) } +#ifndef HAVE_W32_SYSTEM /* The signal handler for this program. It is expected to be run in its own trhead and not in the context of a signal handler. */ static void @@ -1765,7 +1725,6 @@ handle_signal (int signo) { switch (signo) { -#ifndef HAVE_W32_SYSTEM case SIGHUP: agent_sighup_action (); break; @@ -1787,8 +1746,8 @@ handle_signal (int signo) if (!shutdown_pending) log_info ("SIGTERM received - shutting down ...\n"); else - log_info ("SIGTERM received - still %ld running threads\n", - pth_ctrl( PTH_CTRL_GETTHREADS )); + log_info ("SIGTERM received - still %i open connections\n", + active_connections); shutdown_pending++; if (shutdown_pending > 2) { @@ -1805,12 +1764,12 @@ handle_signal (int signo) cleanup (); agent_exit (0); break; -#endif + default: log_info ("signal %d received - no action defined\n", signo); } } - +#endif /* Check the nonce on a new connection. This is a NOP unless we we are using our Unix domain socket emulation under Windows. */ @@ -1838,19 +1797,20 @@ start_connection_thread (void *arg) if (check_nonce (ctrl, &socket_nonce)) { - log_error ("handler 0x%lx nonce check FAILED\n", pth_thread_id ()); + log_error ("handler 0x%lx nonce check FAILED\n", + (unsigned long) npth_self()); return NULL; } agent_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("handler 0x%lx for fd %d started\n"), - pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); start_command_handler (ctrl, GNUPG_INVALID_FD, ctrl->thread_startup.fd); if (opt.verbose) log_info (_("handler 0x%lx for fd %d terminated\n"), - pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); agent_deinit_default_ctrl (ctrl); xfree (ctrl); @@ -1870,12 +1830,12 @@ start_connection_thread_ssh (void *arg) agent_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("ssh handler 0x%lx for fd %d started\n"), - pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); start_command_handler_ssh (ctrl, ctrl->thread_startup.fd); if (opt.verbose) log_info (_("ssh handler 0x%lx for fd %d terminated\n"), - pth_thread_id (), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); agent_deinit_default_ctrl (ctrl); xfree (ctrl); @@ -1888,59 +1848,46 @@ start_connection_thread_ssh (void *arg) static void handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) { - pth_attr_t tattr; - pth_event_t ev, time_ev; - sigset_t sigs; - int signo; + npth_attr_t tattr; struct sockaddr_un paddr; socklen_t plen; fd_set fdset, read_fdset; int ret; gnupg_fd_t fd; int nfd; + int saved_errno; + struct timespec abstime; + struct timespec curtime; + struct timespec timeout; +#ifdef HAVE_W32_SYSTEM + HANDLE events[2]; + int events_set; +#else + int signo; +#endif - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); - -#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. 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 ); - { - 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]); - } - } + ret = npth_attr_init(&tattr); + if (ret) + log_fatal ("error allocating thread attributes: %s\n", + gpg_strerror (ret)); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); - pth_sigmask (SIG_UNBLOCK, &sigs, NULL); - ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); +#ifndef HAVE_W32_SYSTEM + npth_sigev_init (); + npth_sigev_add (SIGHUP); + npth_sigev_add (SIGUSR1); + npth_sigev_add (SIGUSR2); + npth_sigev_add (SIGINT); + npth_sigev_add (SIGTERM); + npth_sigev_fini (); #else # ifdef HAVE_W32CE_SYSTEM /* Use a dummy event. */ - sigs = 0; - ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); # else - sigs = 0; - ev = pth_event (PTH_EVENT_HANDLE, get_agent_scd_notify_event ()); - signo = 0; + events[0] = get_agent_scd_notify_event (); + events[1] = INVALID_HANDLE_VALUE; # endif #endif - time_ev = NULL; /* Set a flag to tell call-scd.c that it may enable event notifications. */ @@ -1956,15 +1903,15 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) nfd = FD2INT (listen_fd_ssh); } + npth_clock_gettime (&abstime); + abstime.tv_sec += TIMERTICK_INTERVAL; + for (;;) { - /* 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) + if (active_connections == 0) break; /* ready */ /* Do not accept new connections but keep on running the @@ -1972,88 +1919,55 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) FD_ZERO (&fdset); } - /* Create a timeout event if needed. To help with power saving - we syncronize the ticks to the next full second. */ - if (!time_ev) - { - pth_time_t nexttick; - - nexttick = pth_timeout (TIMERTICK_INTERVAL, 0); - if (nexttick.tv_usec > 10) /* Use a 10 usec threshhold. */ - { - nexttick.tv_sec++; - nexttick.tv_usec = 0; - } - time_ev = pth_event (PTH_EVENT_TIME, nexttick); - } - /* POSIX says that fd_set should be implemented as a structure, thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; - if (time_ev) - pth_event_concat (ev, time_ev, NULL); - - ret = pth_select_ev (nfd+1, &read_fdset, NULL, NULL, NULL, ev); - if (time_ev) - pth_event_isolate (time_ev); - - if (ret == -1) + npth_clock_gettime (&curtime); + if (!(npth_timercmp (&curtime, &abstime, <))) { - if (pth_event_occurred (ev) - || (time_ev && pth_event_occurred (time_ev))) - { - if (pth_event_occurred (ev)) - { -#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE) - agent_sigusr2_action (); -#else - handle_signal (signo); -#endif - } - if (time_ev && pth_event_occurred (time_ev)) - { - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } - continue; - } - log_error (_("pth_select failed: %s - waiting 1s\n"), - strerror (errno)); - pth_sleep (1); - continue; + /* Timeout. */ + handle_tick (); + npth_clock_gettime (&abstime); + abstime.tv_sec += TIMERTICK_INTERVAL; } + npth_timersub (&abstime, &curtime, &timeout); - if (pth_event_occurred (ev)) - { -#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE) - agent_sigusr2_action (); -#else - handle_signal (signo); -#endif - } +#ifndef HAVE_W32_SYSTEM + ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask()); + saved_errno = errno; - if (time_ev && pth_event_occurred (time_ev)) - { - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } + while (npth_sigev_get_pending(&signo)) + handle_signal (signo); +#else + events_set = 0; + ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, events, &events_set); + saved_errno = errno; + /* This is valid even if npth_eselect returns an error. */ + if (events_set & 1) + agent_sigusr2_action (); +#endif - /* 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, NULL); + if (ret == -1 && saved_errno != EINTR) + { + log_error (_("npth_pselect failed: %s - waiting 1s\n"), + strerror (saved_errno)); + npth_sleep (1); + continue; + } + if (ret <= 0) + /* Interrupt or timeout. Will be handled when calculating the + next timeout. */ + continue; if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset)) { ctrl_t ctrl; plen = sizeof paddr; - fd = INT2FD (pth_accept (FD2INT(listen_fd), - (struct sockaddr *)&paddr, &plen)); + fd = INT2FD (npth_accept (FD2INT(listen_fd), + (struct sockaddr *)&paddr, &plen)); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed: %s\n", strerror (errno)); @@ -2073,20 +1987,18 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) } else { - char threadname[50]; + npth_t thread; - snprintf (threadname, sizeof threadname-1, - "conn fd=%d (gpg)", FD2INT(fd)); - threadname[sizeof threadname -1] = 0; - pth_attr_set (tattr, PTH_ATTR_NAME, threadname); ctrl->thread_startup.fd = fd; - if (!pth_spawn (tattr, start_connection_thread, ctrl)) + ret = npth_create (&thread, &tattr, start_connection_thread, ctrl); + if (ret) { log_error ("error spawning connection handler: %s\n", - strerror (errno) ); + strerror (ret)); assuan_sock_close (fd); xfree (ctrl); } + } fd = GNUPG_INVALID_FD; } @@ -2097,8 +2009,8 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) ctrl_t ctrl; plen = sizeof paddr; - fd = INT2FD(pth_accept (FD2INT(listen_fd_ssh), - (struct sockaddr *)&paddr, &plen)); + fd = INT2FD(npth_accept (FD2INT(listen_fd_ssh), + (struct sockaddr *)&paddr, &plen)); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed for ssh: %s\n", strerror (errno)); @@ -2118,18 +2030,15 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) } else { - char threadname[50]; + npth_t thread; agent_init_default_ctrl (ctrl); - snprintf (threadname, sizeof threadname-1, - "conn fd=%d (ssh)", FD2INT(fd)); - threadname[sizeof threadname -1] = 0; - pth_attr_set (tattr, PTH_ATTR_NAME, threadname); ctrl->thread_startup.fd = fd; - if (!pth_spawn (tattr, start_connection_thread_ssh, ctrl) ) + ret = npth_create (&thread, &tattr, start_connection_thread_ssh, ctrl); + if (ret) { log_error ("error spawning ssh connection handler: %s\n", - strerror (errno) ); + strerror (ret)); assuan_sock_close (fd); xfree (ctrl); } @@ -2138,11 +2047,9 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) } } - pth_event_free (ev, PTH_FREE_ALL); - if (time_ev) - pth_event_free (time_ev, PTH_FREE_ALL); cleanup (); log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); + npth_attr_destroy (&tattr); } @@ -2234,7 +2141,9 @@ static void check_own_socket (void) { char *sockname; - pth_attr_t tattr; + npth_t thread; + npth_attr_t tattr; + int err; if (!opt.use_standard_socket) return; /* This check makes only sense in standard socket mode. */ @@ -2246,15 +2155,14 @@ check_own_socket (void) if (!sockname) return; /* Out of memory. */ - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "check-own-socket"); - - if (!pth_spawn (tattr, check_own_socket_thread, sockname)) - log_error ("error spawning check_own_socket_thread: %s\n", - strerror (errno) ); - pth_attr_destroy (tattr); + err = npth_attr_init (&tattr); + if (err) + return; + npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); + err = npth_create (&thread, &tattr, check_own_socket_thread, sockname); + if (err) + log_error ("error spawning check_own_socket_thread: %s\n", strerror (err)); + npth_attr_destroy (&tattr); } diff --git a/agent/trustlist.c b/agent/trustlist.c index 68dd83364..8604d8432 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -26,7 +26,7 @@ #include <assert.h> #include <unistd.h> #include <sys/stat.h> -#include <pth.h> +#include <npth.h> #include "agent.h" #include <assuan.h> /* fixme: need a way to avoid assuan calls here */ @@ -53,7 +53,7 @@ typedef struct trustitem_s trustitem_t; static trustitem_t *trusttable; static size_t trusttablesize; /* A mutex used to protect the table. */ -static pth_mutex_t trusttable_lock; +static npth_mutex_t trusttable_lock; @@ -81,11 +81,13 @@ void initialize_module_trustlist (void) { static int initialized; + int err; if (!initialized) { - if (!pth_mutex_init (&trusttable_lock)) - log_fatal ("error initializing mutex: %s\n", strerror (errno)); + err = npth_mutex_init (&trusttable_lock, NULL); + if (err) + log_fatal ("error initializing mutex: %s\n", strerror (err)); initialized = 1; } } @@ -96,15 +98,21 @@ initialize_module_trustlist (void) static void lock_trusttable (void) { - if (!pth_mutex_acquire (&trusttable_lock, 0, NULL)) - log_fatal ("failed to acquire mutex in %s\n", __FILE__); + int err; + + err = npth_mutex_lock (&trusttable_lock); + if (err) + log_fatal ("failed to acquire mutex in %s: %s\n", __FILE__, strerror (err)); } static void unlock_trusttable (void) { - if (!pth_mutex_release (&trusttable_lock)) - log_fatal ("failed to release mutex in %s\n", __FILE__); + int err; + + err = npth_mutex_unlock (&trusttable_lock); + if (err) + log_fatal ("failed to release mutex in %s: %s\n", __FILE__, strerror (err)); } |