mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
Initial port to Npth.
This commit is contained in:
parent
6cf8890dc1
commit
2959e9e4d1
43 changed files with 1012 additions and 1058 deletions
|
@ -1,3 +1,7 @@
|
|||
2011-10-13 Marcus Brinkmann <marcus@g10code.com>
|
||||
|
||||
* Makefile.am, apdu.c, app.c, command.c, scdaemon.c: Port to Npth.
|
||||
|
||||
2011-08-10 Werner Koch <wk@g10code.com>
|
||||
|
||||
* command.c (cmd_killscd): Use the new assuan force close flag
|
||||
|
|
|
@ -27,7 +27,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
|
|||
include $(top_srcdir)/am/cmacros.am
|
||||
|
||||
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) \
|
||||
$(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS)
|
||||
$(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS)
|
||||
|
||||
|
||||
card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c
|
||||
|
@ -42,7 +42,7 @@ scdaemon_SOURCES = \
|
|||
|
||||
|
||||
scdaemon_LDADD = $(libcommonpth) ../gl/libgnu.a \
|
||||
$(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \
|
||||
$(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
|
||||
$(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \
|
||||
$(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV)
|
||||
|
||||
|
@ -60,7 +60,7 @@ scdaemon_LDADD = $(libcommonpth) ../gl/libgnu.a \
|
|||
#sc_copykeys_LDADD = \
|
||||
# ../jnlib/libjnlib.a ../common/libcommon.a \
|
||||
# ../common/libsimple-pwquery.a \
|
||||
# $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \
|
||||
# $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \
|
||||
# $(LIBUSB_LIBS) \
|
||||
# -lgpg-error @LIBINTL@ @DL_LIBS@
|
||||
#
|
||||
|
|
71
scd/apdu.c
71
scd/apdu.c
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
/* NOTE: This module is also used by other software, thus the use of
|
||||
the macro USE_GNU_PTH is mandatory. For GnuPG this macro is
|
||||
the macro USE_NPTH is mandatory. For GnuPG this macro is
|
||||
guaranteed to be defined true. */
|
||||
|
||||
#include <config.h>
|
||||
|
@ -29,10 +29,10 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#ifdef USE_GNU_PTH
|
||||
#ifdef USE_NPTH
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <pth.h>
|
||||
# include <npth.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
|||
|
||||
/* Due to conflicting use of threading libraries we usually can't link
|
||||
against libpcsclite. Instead we use a wrapper program. */
|
||||
#ifdef USE_GNU_PTH
|
||||
#ifdef USE_NPTH
|
||||
#if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
|
||||
#define NEED_PCSC_WRAPPER 1
|
||||
#endif
|
||||
|
@ -139,9 +139,9 @@ struct reader_table_s {
|
|||
not yet been read; i.e. the card is not
|
||||
ready for use. */
|
||||
unsigned int change_counter;
|
||||
#ifdef USE_GNU_PTH
|
||||
#ifdef USE_NPTH
|
||||
int lock_initialized;
|
||||
pth_mutex_t lock;
|
||||
npth_mutex_t lock;
|
||||
#endif
|
||||
};
|
||||
typedef struct reader_table_s *reader_table_t;
|
||||
|
@ -329,6 +329,7 @@ static int
|
|||
new_reader_slot (void)
|
||||
{
|
||||
int i, reader = -1;
|
||||
int err;
|
||||
|
||||
for (i=0; i < MAX_READER; i++)
|
||||
{
|
||||
|
@ -340,17 +341,18 @@ new_reader_slot (void)
|
|||
log_error ("new_reader_slot: out of slots\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef USE_GNU_PTH
|
||||
#ifdef USE_NPTH
|
||||
if (!reader_table[reader].lock_initialized)
|
||||
{
|
||||
if (!pth_mutex_init (&reader_table[reader].lock))
|
||||
err = npth_mutex_init (&reader_table[reader].lock, NULL);
|
||||
if (err)
|
||||
{
|
||||
log_error ("error initializing mutex: %s\n", strerror (errno));
|
||||
log_error ("error initializing mutex: %s\n", strerror (err));
|
||||
return -1;
|
||||
}
|
||||
reader_table[reader].lock_initialized = 1;
|
||||
}
|
||||
#endif /*USE_GNU_PTH*/
|
||||
#endif /*USE_NPTH*/
|
||||
reader_table[reader].connect_card = NULL;
|
||||
reader_table[reader].disconnect_card = NULL;
|
||||
reader_table[reader].close_reader = NULL;
|
||||
|
@ -666,8 +668,8 @@ writen (int fd, const void *buf, size_t nbytes)
|
|||
|
||||
while (nleft > 0)
|
||||
{
|
||||
#ifdef USE_GNU_PTH
|
||||
nwritten = pth_write (fd, buf, nleft);
|
||||
#ifdef USE_NPTH
|
||||
nwritten = npth_write (fd, buf, nleft);
|
||||
#else
|
||||
nwritten = write (fd, buf, nleft);
|
||||
#endif
|
||||
|
@ -692,11 +694,11 @@ readn (int fd, void *buf, size_t buflen, size_t *nread)
|
|||
|
||||
while (nleft > 0)
|
||||
{
|
||||
#ifdef USE_GNU_PTH
|
||||
#ifdef USE_NPTH
|
||||
# ifdef HAVE_W32_SYSTEM
|
||||
# error Cannot use pth_read here because it expects a system HANDLE.
|
||||
# error Cannot use npth_read here because it expects a system HANDLE.
|
||||
# endif
|
||||
n = pth_read (fd, buf, nleft);
|
||||
n = npth_read (fd, buf, nleft);
|
||||
#else
|
||||
n = read (fd, buf, nleft);
|
||||
#endif
|
||||
|
@ -1698,8 +1700,8 @@ open_pcsc_reader_wrapped (const char *portstr)
|
|||
slotp->pcsc.rsp_fd = rp[0];
|
||||
|
||||
/* Wait for the intermediate child to terminate. */
|
||||
#ifdef USE_GNU_PTH
|
||||
#define WAIT pth_waitpid
|
||||
#ifdef USE_NPTH
|
||||
#define WAIT npth_waitpid
|
||||
#else
|
||||
#define WAIT waitpid
|
||||
#endif
|
||||
|
@ -2305,38 +2307,47 @@ open_rapdu_reader (int portno,
|
|||
static int
|
||||
lock_slot (int slot)
|
||||
{
|
||||
#ifdef USE_GNU_PTH
|
||||
if (!pth_mutex_acquire (&reader_table[slot].lock, 0, NULL))
|
||||
#ifdef USE_NPTH
|
||||
int err;
|
||||
|
||||
err = npth_mutex_lock (&reader_table[slot].lock);
|
||||
if (err)
|
||||
{
|
||||
log_error ("failed to acquire apdu lock: %s\n", strerror (errno));
|
||||
log_error ("failed to acquire apdu lock: %s\n", strerror (err));
|
||||
return SW_HOST_LOCKING_FAILED;
|
||||
}
|
||||
#endif /*USE_GNU_PTH*/
|
||||
#endif /*USE_NPTH*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
trylock_slot (int slot)
|
||||
{
|
||||
#ifdef USE_GNU_PTH
|
||||
if (!pth_mutex_acquire (&reader_table[slot].lock, TRUE, NULL))
|
||||
#ifdef USE_NPTH
|
||||
int err;
|
||||
|
||||
err = npth_mutex_trylock (&reader_table[slot].lock);
|
||||
if (err == EBUSY)
|
||||
return SW_HOST_BUSY;
|
||||
else if (err)
|
||||
{
|
||||
if (errno == EBUSY)
|
||||
return SW_HOST_BUSY;
|
||||
log_error ("failed to acquire apdu lock: %s\n", strerror (errno));
|
||||
log_error ("failed to acquire apdu lock: %s\n", strerror (err));
|
||||
return SW_HOST_LOCKING_FAILED;
|
||||
}
|
||||
#endif /*USE_GNU_PTH*/
|
||||
#endif /*USE_NPTH*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
unlock_slot (int slot)
|
||||
{
|
||||
#ifdef USE_GNU_PTH
|
||||
if (!pth_mutex_release (&reader_table[slot].lock))
|
||||
#ifdef USE_NPTH
|
||||
int err;
|
||||
|
||||
err = npth_mutex_unlock (&reader_table[slot].lock);
|
||||
if (err)
|
||||
log_error ("failed to release apdu lock: %s\n", strerror (errno));
|
||||
#endif /*USE_GNU_PTH*/
|
||||
#endif /*USE_NPTH*/
|
||||
}
|
||||
|
||||
|
||||
|
|
49
scd/app.c
49
scd/app.c
|
@ -22,7 +22,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pth.h>
|
||||
#include <npth.h>
|
||||
|
||||
#include "scdaemon.h"
|
||||
#include "app-common.h"
|
||||
|
@ -37,7 +37,7 @@
|
|||
static struct
|
||||
{
|
||||
int initialized;
|
||||
pth_mutex_t lock;
|
||||
npth_mutex_t lock;
|
||||
app_t app; /* Application context in use or NULL. */
|
||||
app_t last_app; /* Last application object used as this slot or NULL. */
|
||||
} lock_table[10];
|
||||
|
@ -72,30 +72,30 @@ print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
|
|||
static gpg_error_t
|
||||
lock_reader (int slot, ctrl_t ctrl)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int res;
|
||||
|
||||
if (slot < 0 || slot >= DIM (lock_table))
|
||||
return gpg_error (slot<0? GPG_ERR_INV_VALUE : GPG_ERR_RESOURCE_LIMIT);
|
||||
|
||||
if (!lock_table[slot].initialized)
|
||||
{
|
||||
if (!pth_mutex_init (&lock_table[slot].lock))
|
||||
res = npth_mutex_init (&lock_table[slot].lock, NULL);
|
||||
if (res)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error initializing mutex: %s\n", strerror (errno));
|
||||
return err;
|
||||
log_error ("error initializing mutex: %s\n", strerror (res));
|
||||
return gpg_error_from_errno (res);
|
||||
}
|
||||
lock_table[slot].initialized = 1;
|
||||
lock_table[slot].app = NULL;
|
||||
lock_table[slot].last_app = NULL;
|
||||
}
|
||||
|
||||
if (!pth_mutex_acquire (&lock_table[slot].lock, 0, NULL))
|
||||
res = npth_mutex_lock (&lock_table[slot].lock);
|
||||
if (res)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("failed to acquire APP lock for slot %d: %s\n",
|
||||
slot, strerror (errno));
|
||||
return err;
|
||||
slot, strerror (res));
|
||||
return gpg_error_from_errno (res);
|
||||
}
|
||||
|
||||
apdu_set_progress_cb (slot, print_progress_line, ctrl);
|
||||
|
@ -107,32 +107,18 @@ lock_reader (int slot, ctrl_t ctrl)
|
|||
static void
|
||||
unlock_reader (int slot)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (slot < 0 || slot >= DIM (lock_table)
|
||||
|| !lock_table[slot].initialized)
|
||||
log_bug ("unlock_reader called for invalid slot %d\n", slot);
|
||||
|
||||
apdu_set_progress_cb (slot, NULL, NULL);
|
||||
|
||||
if (!pth_mutex_release (&lock_table[slot].lock))
|
||||
res = npth_mutex_unlock (&lock_table[slot].lock);
|
||||
if (res)
|
||||
log_error ("failed to release APP lock for slot %d: %s\n",
|
||||
slot, strerror (errno));
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
slot, strerror (res));
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,8 +132,7 @@ app_dump_state (void)
|
|||
for (slot=0; slot < DIM (lock_table); slot++)
|
||||
if (lock_table[slot].initialized)
|
||||
{
|
||||
log_info ("app_dump_state: slot=%d lock=", slot);
|
||||
dump_mutex_state (&lock_table[slot].lock);
|
||||
log_info ("app_dump_state: slot=%d", slot);
|
||||
if (lock_table[slot].app)
|
||||
{
|
||||
log_printf (" app=%p", lock_table[slot].app);
|
||||
|
|
|
@ -85,9 +85,9 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_PTH
|
||||
# include <pth.h>
|
||||
#endif /*HAVE_PTH*/
|
||||
#ifdef HAVE_NPTH
|
||||
# include <npth.h>
|
||||
#endif /*HAVE_NPTH*/
|
||||
|
||||
#include <usb.h>
|
||||
|
||||
|
@ -318,7 +318,7 @@ set_msg_len (unsigned char *msg, unsigned int length)
|
|||
static void
|
||||
my_sleep (int seconds)
|
||||
{
|
||||
#ifdef HAVE_PTH
|
||||
#ifdef HAVE_NPTH
|
||||
/* With Pth we also call the standard sleep(0) so that the process
|
||||
may give up its timeslot. */
|
||||
if (!seconds)
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#ifdef USE_GNU_PTH
|
||||
# include <pth.h>
|
||||
#ifdef USE_NPTH
|
||||
# include <npth.h>
|
||||
#endif
|
||||
|
||||
#include "scdaemon.h"
|
||||
|
@ -147,7 +147,7 @@ static struct server_local_s *locked_session;
|
|||
|
||||
/* While doing a reset we need to make sure that the ticker does not
|
||||
call scd_update_reader_status_file while we are using it. */
|
||||
static pth_mutex_t status_file_update_lock;
|
||||
static npth_mutex_t status_file_update_lock;
|
||||
|
||||
|
||||
/*-- Local prototypes --*/
|
||||
|
@ -164,10 +164,12 @@ void
|
|||
initialize_module_command (void)
|
||||
{
|
||||
static int initialized;
|
||||
int err;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
if (pth_mutex_init (&status_file_update_lock))
|
||||
err = npth_mutex_init (&status_file_update_lock, NULL);
|
||||
if (!err)
|
||||
initialized = 1;
|
||||
}
|
||||
}
|
||||
|
@ -279,6 +281,7 @@ static void
|
|||
do_reset (ctrl_t ctrl, int send_reset)
|
||||
{
|
||||
int slot = ctrl->reader_slot;
|
||||
int err;
|
||||
|
||||
if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
|
||||
BUG ();
|
||||
|
@ -326,16 +329,20 @@ do_reset (ctrl_t ctrl, int send_reset)
|
|||
try to update the file. Calling update_reader_status_file is
|
||||
required to get hold of the new status of the card in the slot
|
||||
table. */
|
||||
if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
|
||||
err = npth_mutex_lock (&status_file_update_lock);
|
||||
if (err)
|
||||
{
|
||||
log_error ("failed to acquire status_fle_update lock\n");
|
||||
log_error ("failed to acquire status_fle_update lock: %s\n",
|
||||
strerror (err));
|
||||
ctrl->reader_slot = -1;
|
||||
return;
|
||||
}
|
||||
update_reader_status_file (0); /* Update slot status table. */
|
||||
update_card_removed (slot, 0); /* Clear card_removed flag. */
|
||||
if (!pth_mutex_release (&status_file_update_lock))
|
||||
log_error ("failed to release status_file_update lock\n");
|
||||
err = npth_mutex_unlock (&status_file_update_lock);
|
||||
if (err)
|
||||
log_error ("failed to release status_file_update lock: %s\n",
|
||||
strerror (err));
|
||||
|
||||
/* Do this last, so that the update_card_removed above does its job. */
|
||||
ctrl->reader_slot = -1;
|
||||
|
@ -1548,18 +1555,18 @@ cmd_lock (assuan_context_t ctx, char *line)
|
|||
else
|
||||
locked_session = ctrl->server_local;
|
||||
|
||||
#ifdef USE_GNU_PTH
|
||||
#ifdef USE_NPTH
|
||||
if (rc && has_option (line, "--wait"))
|
||||
{
|
||||
rc = 0;
|
||||
pth_sleep (1); /* Better implement an event mechanism. However,
|
||||
for card operations this should be
|
||||
sufficient. */
|
||||
npth_sleep (1); /* Better implement an event mechanism. However,
|
||||
for card operations this should be
|
||||
sufficient. */
|
||||
/* FIXME: Need to check that the connection is still alive.
|
||||
This can be done by issuing status messages. */
|
||||
goto retry;
|
||||
}
|
||||
#endif /*USE_GNU_PTH*/
|
||||
#endif /*USE_NPTH*/
|
||||
|
||||
if (rc)
|
||||
log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
|
||||
|
@ -2325,9 +2332,13 @@ update_reader_status_file (int set_card_removed_flag)
|
|||
void
|
||||
scd_update_reader_status_file (void)
|
||||
{
|
||||
if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL))
|
||||
int err;
|
||||
err = npth_mutex_lock (&status_file_update_lock);
|
||||
if (err)
|
||||
return; /* locked - give up. */
|
||||
update_reader_status_file (1);
|
||||
if (!pth_mutex_release (&status_file_update_lock))
|
||||
log_error ("failed to release status_file_update lock\n");
|
||||
err = npth_mutex_unlock (&status_file_update_lock);
|
||||
if (err)
|
||||
log_error ("failed to release status_file_update lock: %s\n",
|
||||
strerror (err));
|
||||
}
|
||||
|
|
214
scd/scdaemon.c
214
scd/scdaemon.c
|
@ -1,3 +1,5 @@
|
|||
// FIXME: Active connections
|
||||
|
||||
/* scdaemon.c - The GnuPG Smartcard Daemon
|
||||
* Copyright (C) 2001, 2002, 2004, 2005,
|
||||
* 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
|
@ -35,7 +37,7 @@
|
|||
#endif /*HAVE_W32_SYSTEM*/
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <pth.h>
|
||||
#include <npth.h>
|
||||
|
||||
#define JNLIB_NEED_LOG_LOGV
|
||||
#define JNLIB_NEED_AFLOCAL
|
||||
|
@ -167,7 +169,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||
easy way to block on card status changes it is the best we can do.
|
||||
For PC/SC we could in theory use an extra thread to wait for status
|
||||
changes but that requires a native thread because there is no way
|
||||
to make the underlying PC/SC card change function block using a Pth
|
||||
to make the underlying PC/SC card change function block using a Npth
|
||||
mechanism. Given that a native thread could only be used under W32
|
||||
we don't do that at all. */
|
||||
#define TIMERTICK_INTERVAL_SEC (0)
|
||||
|
@ -204,14 +206,9 @@ static void *start_connection_thread (void *arg);
|
|||
static void handle_connections (int listen_fd);
|
||||
|
||||
/* Pth wrapper function definitions. */
|
||||
ASSUAN_SYSTEM_PTH_IMPL;
|
||||
|
||||
GCRY_THREAD_OPTION_PTH_IMPL;
|
||||
static int fixed_gcry_pth_init (void)
|
||||
{
|
||||
return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0;
|
||||
}
|
||||
ASSUAN_SYSTEM_NPTH_IMPL;
|
||||
|
||||
static int active_connections;
|
||||
|
||||
|
||||
static char *
|
||||
|
@ -272,18 +269,18 @@ my_strusage (int level)
|
|||
static int
|
||||
tid_log_callback (unsigned long *rvalue)
|
||||
{
|
||||
#ifdef PTH_HAVE_PTH_THREAD_ID
|
||||
*rvalue = pth_thread_id ();
|
||||
#else
|
||||
*rvalue = (unsigned long)pth_self ();
|
||||
#endif
|
||||
int len = sizeof (*rvalue);
|
||||
npth_t thread;
|
||||
|
||||
thread = npth_self ();
|
||||
if (sizeof (thread) < len)
|
||||
len = sizeof (thread);
|
||||
memcpy (rvalue, &thread, len);
|
||||
|
||||
return 2; /* Use use hex representation. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Setup the debugging. With a LEVEL of NULL only the active debug
|
||||
flags are propagated to the subsystems. With LEVEL set, a specific
|
||||
set of debug flags is set; thus overriding all flags already
|
||||
|
@ -374,7 +371,6 @@ main (int argc, char **argv )
|
|||
{
|
||||
ARGPARSE_ARGS pargs;
|
||||
int orig_argc;
|
||||
gpg_error_t err;
|
||||
char **orig_argv;
|
||||
FILE *configfp = NULL;
|
||||
char *configname = NULL;
|
||||
|
@ -396,6 +392,8 @@ main (int argc, char **argv )
|
|||
int allow_coredump = 0;
|
||||
int standard_socket = 0;
|
||||
struct assuan_malloc_hooks malloc_hooks;
|
||||
int res;
|
||||
npth_t pipecon_handler;
|
||||
|
||||
set_strusage (my_strusage);
|
||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||
|
@ -408,16 +406,7 @@ main (int argc, char **argv )
|
|||
i18n_init ();
|
||||
init_common_subsystems (&argc, &argv);
|
||||
|
||||
|
||||
/* 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));
|
||||
}
|
||||
npth_init ();
|
||||
|
||||
/* Check that the libraries are suitable. Do it here because
|
||||
the option parsing may need services of the library */
|
||||
|
@ -434,7 +423,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);
|
||||
|
||||
|
@ -697,7 +686,7 @@ main (int argc, char **argv )
|
|||
{
|
||||
/* This is the simple pipe based server */
|
||||
ctrl_t ctrl;
|
||||
pth_attr_t tattr;
|
||||
npth_attr_t tattr;
|
||||
int fd = -1;
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
|
@ -736,10 +725,14 @@ main (int argc, char **argv )
|
|||
socket_name, &socket_nonce));
|
||||
}
|
||||
|
||||
tattr = pth_attr_new();
|
||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
||||
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024);
|
||||
pth_attr_set (tattr, PTH_ATTR_NAME, "pipe-connection");
|
||||
res = npth_attr_init (&tattr);
|
||||
if (res)
|
||||
{
|
||||
log_error ("error allocating thread attributes: %s\n",
|
||||
strerror (res));
|
||||
scd_exit (2);
|
||||
}
|
||||
npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
|
||||
|
||||
ctrl = xtrycalloc (1, sizeof *ctrl);
|
||||
if ( !ctrl )
|
||||
|
@ -749,13 +742,16 @@ main (int argc, char **argv )
|
|||
scd_exit (2);
|
||||
}
|
||||
ctrl->thread_startup.fd = GNUPG_INVALID_FD;
|
||||
if ( !pth_spawn (tattr, start_connection_thread, ctrl) )
|
||||
res = npth_create (&pipecon_handler, &tattr, start_connection_thread, ctrl);
|
||||
if (res)
|
||||
{
|
||||
log_error ("error spawning pipe connection handler: %s\n",
|
||||
strerror (errno) );
|
||||
strerror (res) );
|
||||
xfree (ctrl);
|
||||
scd_exit (2);
|
||||
}
|
||||
npth_setname_np (pipecon_handler, "pipe-connection");
|
||||
npth_attr_destroy (&tattr);
|
||||
|
||||
/* We run handle_connection to wait for the shutdown signal and
|
||||
to run the ticker stuff. */
|
||||
|
@ -966,8 +962,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 running threads\n",
|
||||
active_connections);
|
||||
shutdown_pending++;
|
||||
if (shutdown_pending > 2)
|
||||
{
|
||||
|
@ -1161,9 +1157,7 @@ start_connection_thread (void *arg)
|
|||
static void
|
||||
handle_connections (int listen_fd)
|
||||
{
|
||||
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;
|
||||
|
@ -1171,25 +1165,27 @@ handle_connections (int listen_fd)
|
|||
int ret;
|
||||
int fd;
|
||||
int nfd;
|
||||
struct timespec abstime;
|
||||
struct timespec curtime;
|
||||
struct timespec timeout;
|
||||
int saved_errno;
|
||||
|
||||
tattr = pth_attr_new();
|
||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
||||
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024);
|
||||
ret = npth_attr_init(&tattr);
|
||||
/* FIXME: Check error. */
|
||||
npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM /* fixme */
|
||||
sigemptyset (&sigs );
|
||||
sigaddset (&sigs, SIGHUP);
|
||||
sigaddset (&sigs, SIGUSR1);
|
||||
sigaddset (&sigs, SIGUSR2);
|
||||
sigaddset (&sigs, SIGINT);
|
||||
sigaddset (&sigs, SIGTERM);
|
||||
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
|
||||
sigs = 0;
|
||||
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
|
||||
#endif
|
||||
time_ev = NULL;
|
||||
|
||||
FD_ZERO (&fdset);
|
||||
nfd = 0;
|
||||
|
@ -1199,13 +1195,17 @@ handle_connections (int listen_fd)
|
|||
nfd = listen_fd;
|
||||
}
|
||||
|
||||
npth_clock_gettime (&curtime);
|
||||
timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
|
||||
timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
|
||||
npth_timeradd (&curtime, &timeout, &abstime);
|
||||
/* We only require abstime here. The others will be reused. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
sigset_t oldsigs;
|
||||
|
||||
if (shutdown_pending)
|
||||
{
|
||||
if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1)
|
||||
if (active_connections == 0)
|
||||
break; /* ready */
|
||||
|
||||
/* Do not accept anymore connections but wait for existing
|
||||
|
@ -1216,80 +1216,47 @@ handle_connections (int listen_fd)
|
|||
listen_fd = -1;
|
||||
}
|
||||
|
||||
/* Create a timeout event if needed. Round it up to the next
|
||||
microsecond interval to help with power saving. */
|
||||
if (!time_ev)
|
||||
{
|
||||
pth_time_t nexttick = pth_timeout (TIMERTICK_INTERVAL_SEC,
|
||||
TIMERTICK_INTERVAL_USEC/2);
|
||||
if ((nexttick.tv_usec % (TIMERTICK_INTERVAL_USEC/2)) > 10)
|
||||
{
|
||||
nexttick.tv_usec = ((nexttick.tv_usec
|
||||
/(TIMERTICK_INTERVAL_USEC/2))
|
||||
+ 1) * (TIMERTICK_INTERVAL_USEC/2);
|
||||
if (nexttick.tv_usec >= 1000000)
|
||||
{
|
||||
nexttick.tv_sec++;
|
||||
nexttick.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
time_ev = pth_event (PTH_EVENT_TIME, nexttick);
|
||||
}
|
||||
npth_clock_gettime (&curtime);
|
||||
if (!(npth_timercmp (&curtime, &abstime, <)))
|
||||
{
|
||||
/* Timeout. */
|
||||
handle_tick ();
|
||||
timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
|
||||
timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
|
||||
npth_timeradd (&curtime, &timeout, &abstime);
|
||||
}
|
||||
npth_timersub (&abstime, &curtime, &timeout);
|
||||
|
||||
/* 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);
|
||||
ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
|
||||
saved_errno = errno;
|
||||
|
||||
if (ret == -1)
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
while (npth_sigev_get_pending(&signo))
|
||||
handle_signal (signo);
|
||||
#endif
|
||||
|
||||
if (ret == -1 && saved_errno != EINTR)
|
||||
{
|
||||
if (pth_event_occurred (ev)
|
||||
|| (time_ev && pth_event_occurred (time_ev)))
|
||||
{
|
||||
if (pth_event_occurred (ev))
|
||||
handle_signal (signo);
|
||||
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);
|
||||
log_error (_("pth_pselect failed: %s - waiting 1s\n"),
|
||||
strerror (saved_errno));
|
||||
npth_sleep (1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pth_event_occurred (ev))
|
||||
{
|
||||
handle_signal (signo);
|
||||
}
|
||||
|
||||
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 - we are handling here - to be delivered to a new
|
||||
thread. Thus we need to block those signals. */
|
||||
pth_sigmask (SIG_BLOCK, &sigs, &oldsigs);
|
||||
if (ret <= 0)
|
||||
/* Timeout. Will be handled when calculating the next timeout. */
|
||||
continue;
|
||||
|
||||
if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
|
||||
plen = sizeof paddr;
|
||||
fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
|
||||
fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
|
||||
if (fd == -1)
|
||||
{
|
||||
log_error ("accept failed: %s\n", strerror (errno));
|
||||
|
@ -1303,30 +1270,27 @@ handle_connections (int listen_fd)
|
|||
else
|
||||
{
|
||||
char threadname[50];
|
||||
npth_t thread;
|
||||
|
||||
snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd);
|
||||
threadname[sizeof threadname -1] = 0;
|
||||
pth_attr_set (tattr, PTH_ATTR_NAME, threadname);
|
||||
ctrl->thread_startup.fd = INT2FD (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));
|
||||
xfree (ctrl);
|
||||
close (fd);
|
||||
}
|
||||
else
|
||||
npth_setname_np (thread, threadname);
|
||||
}
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
/* Restore the signal mask. */
|
||||
pth_sigmask (SIG_SETMASK, &oldsigs, NULL);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue