aboutsummaryrefslogtreecommitdiffstats
path: root/scd/scdaemon.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2004-04-20 14:17:10 +0000
committerWerner Koch <[email protected]>2004-04-20 14:17:10 +0000
commite950b01ff56c86d8e04b75a7bac4234afc939199 (patch)
treedf584bfcd6ea6348371a037e2983c393c3f02a0d /scd/scdaemon.c
parentInclude jnlib/types.h and remove our own (diff)
downloadgnupg-e950b01ff56c86d8e04b75a7bac4234afc939199.tar.gz
gnupg-e950b01ff56c86d8e04b75a7bac4234afc939199.zip
* pcsc-wrapper.c: New.
* Makefile.am (pkglib_PROGRAMS): Install it here. * apdu.c (writen, readn): New. (open_pcsc_reader, pcsc_send_apdu, close_pcsc_reader): Use the pcsc-wrapper if we are using Pth.
Diffstat (limited to 'scd/scdaemon.c')
-rw-r--r--scd/scdaemon.c154
1 files changed, 152 insertions, 2 deletions
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index bc9d90b72..aabd38861 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -33,6 +33,9 @@
#include <sys/un.h>
#include <unistd.h>
#include <signal.h>
+#ifdef USE_GNU_PTH
+# include <pth.h>
+#endif
#define JNLIB_NEED_LOG_LOGV
#include "scdaemon.h"
@@ -131,12 +134,24 @@ static ARGPARSE_OPTS opts[] = {
static volatile int caught_fatal_sig = 0;
+/* Flag to indicate that a shutdown was requested. */
+static int shutdown_pending;
+
/* It is possible that we are currently running under setuid permissions */
static int maybe_setuid = 1;
/* Name of the communication socket */
static char socket_name[128];
+
+#ifdef USE_GNU_PTH
+/* Pth wrapper function definitions. */
+GCRY_THREAD_OPTION_PTH_IMPL;
+
+static void *ticker_thread (void *arg);
+#endif /*USE_GNU_PTH*/
+
+
static const char *
my_strusage (int level)
{
@@ -287,6 +302,7 @@ main (int argc, char **argv )
{
ARGPARSE_ARGS pargs;
int orig_argc;
+ gpg_error_t err;
int may_coredump;
char **orig_argv;
FILE *configfp = NULL;
@@ -318,7 +334,18 @@ main (int argc, char **argv )
i18n_init ();
- /* check that the libraries are suitable. Do it here because
+ /* Libgcrypt requires us to register the threading model first.
+ Note that this will also do the pth_init. */
+#ifdef USE_GNU_PTH
+ 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 /*USE_GNU_PTH*/
+
+ /* Check that the libraries are suitable. Do it here because
the option parsing may need services of the library */
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
{
@@ -568,7 +595,21 @@ main (int argc, char **argv )
if (pipe_server)
- { /* this is the simple pipe based server */
+ { /* This is the simple pipe based server */
+#ifdef USE_GNU_PTH
+ pth_attr_t tattr;
+
+ tattr = pth_attr_new();
+ pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
+ pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
+ pth_attr_set (tattr, PTH_ATTR_NAME, "ticker");
+
+ if (!pth_spawn (tattr, ticker_thread, NULL))
+ {
+ log_error ("error spawning ticker thread: %s\n", strerror (errno));
+ scd_exit (2);
+ }
+#endif /*USE_GNU_PTH*/
scd_command_handler (-1);
}
else if (!is_daemon)
@@ -780,6 +821,115 @@ scd_exit (int rc)
void
scd_init_default_ctrl (CTRL ctrl)
{
+ ctrl->reader_slot = -1;
+}
+
+
+#ifdef USE_GNU_PTH
+
+static void
+handle_signal (int signo)
+{
+ switch (signo)
+ {
+ case SIGHUP:
+ log_info ("SIGHUP received - "
+ "re-reading configuration and resetting cards\n");
+/* reread_configuration (); */
+ break;
+
+ case SIGUSR1:
+ if (opt.verbose < 5)
+ opt.verbose++;
+ log_info ("SIGUSR1 received - verbosity set to %d\n", opt.verbose);
+ break;
+
+ case SIGUSR2:
+ if (opt.verbose)
+ opt.verbose--;
+ log_info ("SIGUSR2 received - verbosity set to %d\n", opt.verbose );
+ break;
+
+ case SIGTERM:
+ 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 ));
+ shutdown_pending++;
+ if (shutdown_pending > 2)
+ {
+ log_info ("shutdown forced\n");
+ log_info ("%s %s stopped\n", strusage(11), strusage(13) );
+ cleanup ();
+ scd_exit (0);
+ }
+ break;
+
+ case SIGINT:
+ log_info ("SIGINT received - immediate shutdown\n");
+ log_info( "%s %s stopped\n", strusage(11), strusage(13));
+ cleanup ();
+ scd_exit (0);
+ break;
+ default:
+ log_info ("signal %d received - no action defined\n", signo);
+ }
}
+static void
+handle_tick (void)
+{
+ scd_update_reader_status_file ();
+}
+
+static void *
+ticker_thread (void *dummy_arg)
+{
+ pth_event_t sigs_ev, time_ev = NULL;
+ sigset_t sigs;
+ int signo;
+
+ sigemptyset (&sigs );
+ sigaddset (&sigs, SIGHUP);
+ sigaddset (&sigs, SIGUSR1);
+ sigaddset (&sigs, SIGUSR2);
+ sigaddset (&sigs, SIGINT);
+ sigaddset (&sigs, SIGTERM);
+ sigs_ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+
+ for (;;)
+ {
+ if (!time_ev)
+ {
+ time_ev = pth_event (PTH_EVENT_TIME, pth_timeout (2, 0));
+ if (time_ev)
+ pth_event_concat (sigs_ev, time_ev, NULL);
+ }
+
+ if (pth_wait (sigs_ev) < 1)
+ continue;
+
+ if (
+#ifdef PTH_STATUS_OCCURRED /* This is Pth 2 */
+ pth_event_status (sigs_ev) == PTH_STATUS_OCCURRED
+#else
+ pth_event_occurred (sigs_ev)
+#endif
+ )
+ handle_signal (signo);
+
+ /* Always run the ticker. */
+ if (!shutdown_pending)
+ {
+ pth_event_isolate (sigs_ev);
+ pth_event_free (time_ev, PTH_FREE_ALL);
+ time_ev = NULL;
+ handle_tick ();
+ }
+ }
+
+ pth_event_free (sigs_ev, PTH_FREE_ALL);
+}
+#endif /*USE_GNU_PTH*/