diff options
Diffstat (limited to 'g13')
-rw-r--r-- | g13/Makefile.am | 4 | ||||
-rw-r--r-- | g13/call-gpg.c | 138 | ||||
-rw-r--r-- | g13/g13.c | 174 | ||||
-rw-r--r-- | g13/runner.c | 29 |
4 files changed, 166 insertions, 179 deletions
diff --git a/g13/Makefile.am b/g13/Makefile.am index b846dcda8..745ec40e6 100644 --- a/g13/Makefile.am +++ b/g13/Makefile.am @@ -26,7 +26,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) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) g13_SOURCES = \ g13.c g13.h \ @@ -43,5 +43,5 @@ g13_SOURCES = \ be-truecrypt.c be-truecrypt.h g13_LDADD = $(libcommonpth) ../gl/libgnu.a \ - $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) diff --git a/g13/call-gpg.c b/g13/call-gpg.c index c2b1e0c41..93b91d5e7 100644 --- a/g13/call-gpg.c +++ b/g13/call-gpg.c @@ -24,7 +24,7 @@ #include <errno.h> #include <time.h> #include <assert.h> -#include <pth.h> +#include <npth.h> #include "g13.h" #include <assuan.h> @@ -163,7 +163,7 @@ struct writer_thread_parms /* The thread started by start_writer. */ static void * -writer_thread (void *arg) +writer_thread_main (void *arg) { struct writer_thread_parms *parm = arg; const char *buffer = parm->data; @@ -173,7 +173,7 @@ writer_thread (void *arg) { ssize_t nwritten; - nwritten = pth_write (parm->fd, buffer, length < 4096? length:4096); + nwritten = npth_write (parm->fd, buffer, length < 4096? length:4096); if (nwritten < 0) { if (errno == EINTR) @@ -199,14 +199,15 @@ writer_thread (void *arg) finished. */ static gpg_error_t start_writer (int fd, const void *data, size_t datalen, - pth_t *r_tid, gpg_error_t *err_addr) + npth_t *r_thread, gpg_error_t *err_addr) { gpg_error_t err; struct writer_thread_parms *parm; - pth_attr_t tattr; - pth_t tid; + npth_attr_t tattr; + npth_t thread; + int ret; - *r_tid = NULL; + memset (r_thread, '\0', sizeof (*r_thread)); *err_addr = 0; parm = xtrymalloc (sizeof *parm); @@ -217,23 +218,22 @@ start_writer (int fd, const void *data, size_t datalen, parm->datalen = datalen; parm->err_addr = err_addr; - tattr = pth_attr_new (); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "fd-writer"); + npth_attr_init (&tattr); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); - tid = pth_spawn (tattr, writer_thread, parm); - if (!tid) + ret = npth_create (&thread, &tattr, writer_thread_main, parm); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("error spawning writer thread: %s\n", gpg_strerror (err)); } else { + npth_setname_np (thread, "fd-writer"); err = 0; - *r_tid = tid; + *r_thread = thread; } - pth_attr_destroy (tattr); + npth_attr_destroy (&tattr); return err; } @@ -251,13 +251,13 @@ struct reader_thread_parms /* The thread started by start_reader. */ static void * -reader_thread (void *arg) +reader_thread_main (void *arg) { struct reader_thread_parms *parm = arg; char buffer[4096]; int nread; - while ( (nread = pth_read (parm->fd, buffer, sizeof buffer)) ) + while ( (nread = npth_read (parm->fd, buffer, sizeof buffer)) ) { if (nread < 0) { @@ -282,14 +282,15 @@ reader_thread (void *arg) is stored at R_TID. After the thread has finished an error from the thread will be stored at ERR_ADDR. */ static gpg_error_t -start_reader (int fd, membuf_t *mb, pth_t *r_tid, gpg_error_t *err_addr) +start_reader (int fd, membuf_t *mb, npth_t *r_thread, gpg_error_t *err_addr) { gpg_error_t err; struct reader_thread_parms *parm; - pth_attr_t tattr; - pth_t tid; + npth_attr_t tattr; + npth_t thread; + int ret; - *r_tid = NULL; + memset (r_thread, '\0', sizeof (*r_thread)); *err_addr = 0; parm = xtrymalloc (sizeof *parm); @@ -299,23 +300,22 @@ start_reader (int fd, membuf_t *mb, pth_t *r_tid, gpg_error_t *err_addr) parm->mb = mb; parm->err_addr = err_addr; - tattr = pth_attr_new (); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "fd-reader"); + npth_attr_init (&tattr); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); - tid = pth_spawn (tattr, reader_thread, parm); - if (!tid) + ret = npth_create (&thread, &tattr, reader_thread_main, parm); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("error spawning reader thread: %s\n", gpg_strerror (err)); } else { + npth_setname_np (thread, "fd-reader"); err = 0; - *r_tid = tid; + *r_thread = thread; } - pth_attr_destroy (tattr); + npth_attr_destroy (&tattr); return err; } @@ -335,12 +335,13 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, assuan_context_t ctx; int outbound_fds[2] = { -1, -1 }; int inbound_fds[2] = { -1, -1 }; - pth_t writer_tid = NULL; - pth_t reader_tid = NULL; + npth_t writer_thread; + npth_t reader_thread; gpg_error_t writer_err, reader_err; membuf_t reader_mb; char line[ASSUAN_LINELENGTH]; strlist_t sl; + int ret; *r_ciph = NULL; *r_ciphlen = 0; @@ -367,7 +368,7 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, /* Start a writer thread to feed the INPUT command of the server. */ err = start_writer (outbound_fds[1], plain, plainlen, - &writer_tid, &writer_err); + &writer_thread, &writer_err); if (err) return err; outbound_fds[1] = -1; /* The thread owns the FD now. */ @@ -375,7 +376,7 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, /* Start a reader thread to eat from the OUTPUT command of the server. */ err = start_reader (inbound_fds[0], &reader_mb, - &reader_tid, &reader_err); + &reader_thread, &reader_err); if (err) return err; outbound_fds[0] = -1; /* The thread owns the FD now. */ @@ -402,13 +403,15 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, } /* Wait for reader and return the data. */ - if (!pth_join (reader_tid, NULL)) + ret = npth_join (reader_thread, NULL); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err)); goto leave; } - reader_tid = NULL; + /* FIXME: Not really valid, as npth_t is an opaque type. */ + memset (&reader_thread, '\0', sizeof (reader_thread)); if (reader_err) { err = reader_err; @@ -417,13 +420,14 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, } /* Wait for the writer to catch a writer error. */ - if (!pth_join (writer_tid, NULL)) + ret = npth_join (writer_thread, NULL); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err)); goto leave; } - writer_tid = NULL; + memset (&writer_thread, '\0', sizeof (writer_thread)); if (writer_err) { err = writer_err; @@ -442,16 +446,11 @@ gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, } leave: - if (reader_tid) - { - pth_cancel (reader_tid); - pth_join (reader_tid, NULL); - } - if (writer_tid) - { - pth_cancel (writer_tid); - pth_join (writer_tid, NULL); - } + /* FIXME: Not valid, as npth_t is an opaque type. */ + if (reader_thread) + npth_detach (reader_thread); + if (writer_thread) + npth_detach (writer_thread); if (outbound_fds[0] != -1) close (outbound_fds[0]); if (outbound_fds[1] != -1) @@ -479,10 +478,11 @@ gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, assuan_context_t ctx; int outbound_fds[2] = { -1, -1 }; int inbound_fds[2] = { -1, -1 }; - pth_t writer_tid = NULL; - pth_t reader_tid = NULL; + npth_t writer_thread; + npth_t reader_thread; gpg_error_t writer_err, reader_err; membuf_t reader_mb; + int ret; *r_plain = NULL; *r_plainlen = 0; @@ -509,7 +509,7 @@ gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, /* Start a writer thread to feed the INPUT command of the server. */ err = start_writer (outbound_fds[1], ciph, ciphlen, - &writer_tid, &writer_err); + &writer_thread, &writer_err); if (err) return err; outbound_fds[1] = -1; /* The thread owns the FD now. */ @@ -517,7 +517,7 @@ gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, /* Start a reader thread to eat from the OUTPUT command of the server. */ err = start_reader (inbound_fds[0], &reader_mb, - &reader_tid, &reader_err); + &reader_thread, &reader_err); if (err) return err; outbound_fds[0] = -1; /* The thread owns the FD now. */ @@ -532,13 +532,14 @@ gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, } /* Wait for reader and return the data. */ - if (!pth_join (reader_tid, NULL)) + ret = npth_join (reader_thread, NULL); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err)); goto leave; } - reader_tid = NULL; + memset (&reader_thread, '\0', sizeof (reader_thread)); if (reader_err) { err = reader_err; @@ -547,13 +548,14 @@ gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, } /* Wait for the writer to catch a writer error. */ - if (!pth_join (writer_tid, NULL)) + ret = npth_join (writer_thread, NULL); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err)); goto leave; } - writer_tid = NULL; + memset (&writer_thread, '\0', sizeof (writer_thread)); if (writer_err) { err = writer_err; @@ -572,16 +574,10 @@ gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, } leave: - if (reader_tid) - { - pth_cancel (reader_tid); - pth_join (reader_tid, NULL); - } - if (writer_tid) - { - pth_cancel (writer_tid); - pth_join (writer_tid, NULL); - } + if (reader_thread) + npth_detach (reader_thread); + if (writer_thread) + npth_detach (writer_thread); if (outbound_fds[0] != -1) close (outbound_fds[0]); if (outbound_fds[1] != -1) @@ -25,7 +25,7 @@ #include <ctype.h> #include <unistd.h> #include <fcntl.h> -#include <pth.h> +#include <npth.h> #include "g13.h" @@ -188,7 +188,7 @@ static unsigned int debug_value; static int shutdown_pending; /* The thread id of the idle task. */ -static pth_t idle_task_tid; +static npth_t idle_task_thread; @@ -199,26 +199,11 @@ static void emergency_cleanup (void); static void start_idle_task (void); static void join_idle_task (void); - -/* Begin Pth wrapper functions. */ -ASSUAN_SYSTEM_PTH_IMPL; - -#if 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 - -/* End Pth wrapper functions. */ - +/* Begin NPth wrapper functions. */ +ASSUAN_SYSTEM_NPTH_IMPL; + static const char * my_strusage( int level ) { @@ -336,7 +321,7 @@ main ( int argc, char **argv) ARGPARSE_ARGS pargs; int orig_argc; char **orig_argv; - gpg_error_t err; + gpg_error_t err = 0; const char *fname; int may_coredump; FILE *configfp = NULL; @@ -368,18 +353,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 Libgcrypt is suitable. */ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) @@ -444,7 +418,7 @@ main ( int argc, char **argv) /* Prepare libassuan. */ assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); setup_libassuan_logging (&opt.debug); /* Setup a default control structure for command line mode. */ @@ -795,7 +769,7 @@ g13_init_default_ctrl (struct server_control_s *ctrl) /* This function is called for each signal we catch. It is run in the - main context or the one of a Pth thread and thus it is not + main context or the one of a NPth thread and thus it is not restricted in what it may do. */ static void handle_signal (int signo) @@ -862,29 +836,30 @@ handle_tick (void) static void * idle_task (void *dummy_arg) { - sigset_t sigs; /* The set of signals we want to catch. */ - pth_event_t ev; /* The main event to catch signals. */ - pth_event_t time_ev; /* The time event. */ int signo; /* The number of a raised signal is stored here. */ + int saved_errno; + struct timespec abstime; + struct timespec curtime; + struct timespec timeout; + int ret; (void)dummy_arg; /* Create the event to catch the signals. */ #ifndef HAVE_W32_SYSTEM - sigemptyset (&sigs ); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); - pth_sigmask (SIG_UNBLOCK, &sigs, NULL); + 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; #endif - ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); - /* The time event neds to computed n tghe fly. */ - time_ev = NULL; + npth_clock_gettime (&abstime); + abstime.tv_sec += TIMERTICK_INTERVAL_SEC; for (;;) { @@ -897,41 +872,40 @@ idle_task (void *dummy_arg) break; /* ready */ } - /* 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; + npth_clock_gettime (&curtime); + if (!(npth_timercmp (&curtime, &abstime, <))) + { + /* Timeout. */ + handle_tick (); + npth_clock_gettime (&abstime); + abstime.tv_sec += TIMERTICK_INTERVAL_SEC; + } + npth_timersub (&abstime, &curtime, &timeout); - nexttick = pth_timeout (TIMERTICK_INTERVAL_SEC, 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); - } + ret = npth_pselect (0, NULL, NULL, NULL, &timeout, npth_sigev_sigmask()); + saved_errno = errno; - pth_event_concat (ev, time_ev, NULL); - pth_wait (ev); - pth_event_isolate (time_ev); +#ifndef HAVE_W32_SYSTEM + while (npth_sigev_get_pending(&signo)) + handle_signal (signo); +#endif - if (pth_event_occurred (ev)) - { - handle_signal (signo); - } + if (ret == -1 && saved_errno != EINTR) + { + log_error (_("npth_pselect failed: %s - waiting 1s\n"), + strerror (saved_errno)); + npth_sleep (1); + continue; + } - if (time_ev && pth_event_occurred (time_ev)) - { - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } + if (ret <= 0) + /* Interrupt or timeout. Will be handled when calculating the + next timeout. */ + continue; + + /* Here one would add processing of file descriptors. */ } - pth_event_free (ev, PTH_FREE_ALL); - if (time_ev) - pth_event_free (time_ev, PTH_FREE_ALL); log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); return NULL; } @@ -941,23 +915,34 @@ idle_task (void *dummy_arg) static void start_idle_task (void) { - pth_attr_t tattr; - pth_t tid; + npth_attr_t tattr; + npth_t thread; + sigset_t sigs; /* The set of signals we want to catch. */ + int err; + + /* These signals should always go to the idle task, so they need to + be blocked everywhere else. We assume start_idle_task is called + from the main thread before any other threads are created. */ + sigemptyset (&sigs); + sigaddset (&sigs, SIGHUP); + sigaddset (&sigs, SIGUSR1); + sigaddset (&sigs, SIGUSR2); + sigaddset (&sigs, SIGINT); + sigaddset (&sigs, SIGTERM); + npth_sigmask (SIG_BLOCK, &sigs, NULL); - tattr = pth_attr_new (); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "idle-task"); + npth_attr_init (&tattr); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); - tid = pth_spawn (tattr, idle_task, NULL); - if (!tid) + err = npth_create (&thread, &tattr, idle_task, NULL); + if (err) { - log_fatal ("error starting idle task: %s\n", - gpg_strerror (gpg_error_from_syserror ())); + log_fatal ("error starting idle task: %s\n", strerror (err)); return; /*NOTREACHED*/ } - idle_task_tid = tid; - pth_attr_destroy (tattr); + npth_setname_np (thread, "idle-task"); + idle_task_thread = thread; + npth_attr_destroy (&tattr); } @@ -965,10 +950,15 @@ start_idle_task (void) static void join_idle_task (void) { - if (idle_task_tid) + int err; + + /* FIXME: This assumes that a valid pthread_t is non-null. That is + not guaranteed. */ + if (idle_task_thread) { - if (!pth_join (idle_task_tid, NULL)) + err = npth_join (idle_task_thread, NULL); + if (err) log_error ("waiting for idle task thread failed: %s\n", - gpg_strerror (gpg_error_from_syserror ())); + strerror (err)); } } diff --git a/g13/runner.c b/g13/runner.c index 7e9c262c3..7680d3d5b 100644 --- a/g13/runner.c +++ b/g13/runner.c @@ -24,7 +24,7 @@ #include <errno.h> #include <unistd.h> #include <assert.h> -#include <pth.h> +#include <npth.h> #include "g13.h" #include "i18n.h" @@ -40,7 +40,7 @@ struct runner_s unsigned int identifier; /* The runner identifier. */ int spawned; /* True if runner_spawn has been called. */ - pth_t threadid; /* The TID of the runner thread. */ + npth_t thread; /* The TID of the runner thread. */ runner_t next_running; /* Builds a list of all running threads. */ int canceled; /* Set if a cancel has already been send once. */ @@ -85,7 +85,7 @@ writen (int fd, const void *buf, size_t nbytes) while (nleft > 0) { - nwritten = pth_write (fd, buf, nleft); + nwritten = npth_write (fd, buf, nleft); if (nwritten < 0) { if (errno == EINTR) @@ -408,8 +408,9 @@ gpg_error_t runner_spawn (runner_t runner) { gpg_error_t err; - pth_attr_t tattr; - pth_t tid; + npth_attr_t tattr; + npth_t thread; + int ret; if (check_already_spawned (runner, "runner_spawn")) return gpg_error (GPG_ERR_BUG); @@ -433,26 +434,26 @@ runner_spawn (runner_t runner) runner->in_fd = -1; /* Now owned by status_fp. */ } - tattr = pth_attr_new (); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 128*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, runner->name); + npth_attr_init (&tattr); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); - tid = pth_spawn (tattr, runner_thread, runner); - if (!tid) + ret = npth_create (&thread, &tattr, runner_thread, runner); + if (ret) { - err = gpg_error_from_syserror (); + err = gpg_error_from_errno (ret); log_error ("error spawning runner thread: %s\n", gpg_strerror (err)); return err; } + npth_setname_np (thread, runner->name); + /* The scheduler has not yet kicked in, thus we can safely set the spawned flag and the tid. */ runner->spawned = 1; - runner->threadid = tid; + runner->thread = thread; runner->next_running = running_threads; running_threads = runner; - pth_attr_destroy (tattr); + npth_attr_destroy (&tattr); /* The runner thread is now runnable. */ |