1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

Port to npth.

* configure.ac: Don't check for PTH but for NPTH.
(AH_BOTTOM): Remove PTH_SYSCALL_SOFT.
(have_pth): Rename to ...
(have_npth): ... this.
(USE_GNU_NPTH): Rename to ...
(USE_GNU_PTH): ... this.
* m4/npth.m4: New file.
* agent/Makefile.am, agent/cache.c, agent/call-pinentry.c,
agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c,
agent/trustlist.c, common/Makefile.am, common/estream.c,
common/exechelp-posix.c, common/exechelp-w32.c,
common/exechelp-w32ce.c, common/http.c, common/init.c,
common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c,
dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c,
dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am,
g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am,
scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c,
scd/scdaemon.c, tools/Makefile.am: Port to npth.
This commit is contained in:
Marcus Brinkmann 2012-01-03 22:12:37 +01:00 committed by Werner Koch
parent 495dc68586
commit 7a7a597827
36 changed files with 969 additions and 1098 deletions

View file

@ -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)

View file

@ -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)
{

View file

@ -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. */

View file

@ -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));
}

View file

@ -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. */

View file

@ -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)
@ -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)
{
@ -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,9 +1848,7 @@ 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;
npth_attr_t tattr;
int signo;
struct sockaddr_un paddr;
socklen_t plen;
@ -1898,37 +1856,23 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
int ret;
gnupg_fd_t fd;
int nfd;
int saved_errno;
struct timespec abstime;
struct timespec curtime;
struct timespec timeout;
tattr = pth_attr_new();
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
ret = npth_attr_init(&tattr);
/* FIXME: Check error. */
npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
#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]);
}
}
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. */
@ -1940,7 +1884,6 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
signo = 0;
# endif
#endif
time_ev = NULL;
/* Set a flag to tell call-scd.c that it may enable event
notifications. */
@ -1956,15 +1899,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 +1915,52 @@ 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);
/* Timeout. */
handle_tick ();
npth_clock_gettime (&abstime);
abstime.tv_sec += TIMERTICK_INTERVAL;
}
npth_timersub (&abstime, &curtime, &timeout);
ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
saved_errno = errno;
#ifndef HAVE_W32_SYSTEM
while (npth_sigev_get_pending(&signo))
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);
#if defined(HAVE_W32_SYSTEM) && defined(PTH_EVENT_HANDLE)
if (pth_event_occurred (ev))
agent_sigusr2_action ();
#endif
if (ret == -1 && saved_errno != EINTR)
{
log_error (_("npth_pselect failed: %s - waiting 1s\n"),
strerror (saved_errno));
npth_sleep (1);
continue;
}
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 ();
}
/* 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 <= 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 +1980,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 +2002,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 +2023,15 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
}
else
{
char threadname[50];
pthread_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 +2040,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 +2134,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 +2148,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);
}

View file

@ -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));
}