diff --git a/assuan/README.1st b/assuan/README.1st index 7b6074ff..6e8d4ec8 100644 --- a/assuan/README.1st +++ b/assuan/README.1st @@ -20,3 +20,6 @@ updating this directory, are: * assuan-io.c ** Don't try to support GNU Pth here. + +* assuan-pipe-connect.c +** Do not install SIGPIPE signal handler here. diff --git a/assuan/assuan-pipe-connect.c b/assuan/assuan-pipe-connect.c index d30c106b..a3ddc224 100644 --- a/assuan/assuan-pipe-connect.c +++ b/assuan/assuan-pipe-connect.c @@ -102,7 +102,9 @@ AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], int *fd_child_list) { +#ifndef _ASSUAN_IN_GPGME static int fixed_signals = 0; +#endif AssuanError err; int rp[2]; int wp[2]; @@ -110,6 +112,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], if (!ctx || !name || !argv || !argv[0]) return ASSUAN_Invalid_Value; +#ifndef _ASSUAN_IN_GPGME if (!fixed_signals) { struct sigaction act; @@ -125,6 +128,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], fixed_signals = 1; /* FIXME: This is not MT safe */ } +#endif if (pipe (rp) < 0) return ASSUAN_General_Error; diff --git a/doc/ChangeLog b/doc/ChangeLog index de523fea..0064e2d2 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2003-10-06 Marcus Brinkmann + + * gpgme.texi (Signal Handling): New section. + 2003-09-14 Marcus Brinkmann * gpgme.texi (Multi Threading): Correct documentation on memory diff --git a/doc/gpgme.texi b/doc/gpgme.texi index c76916e3..48094548 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -107,6 +107,7 @@ Preparation * Using Automake:: Compiler options to be used the easy way. * Using Libtool:: Avoiding compiler options entirely. * Library Version Check:: Getting and verifying the library version. +* Signal Handling:: How @acronym{GPGME} affects signal handling. * Multi Threading:: How @acronym{GPGME} can be used in an MT environment. Protocols and Engines @@ -322,6 +323,7 @@ of the library are verified. * Using Automake:: Compiler options to be used the easy way. * Using Libtool:: Avoiding compiler options entirely. * Library Version Check:: Getting and verifying the library version. +* Signal Handling:: How @acronym{GPGME} affects signal handling. * Multi Threading:: How @acronym{GPGME} can be used in an MT environment. @end menu @@ -518,6 +520,34 @@ like this. @acronym{GPGME} can not do this for you because it would not be thread safe. +@node Signal Handling +@section Signal Handling +@cindex signals +@cindex signal handling + +The @acronym{GPGME} library communicates with child processes (the +crypto engines). If a child process dies unexpectedly, for example +due to a bug, or system problem, a @code{SIGPIPE} signal will be +delivered to the application. The default action is to abort the +program. To protect against this, @code{gpgme_check_version} sets the +@code{SIGPIPE} signal action to @code{SIG_IGN}, which means that the +signal will be ignored. + +@acronym{GPGME} will only do that if the signal action for +@code{SIGPIPE} is @code{SIG_DEF} at the time +@code{gpgme_check_version} is called. If it is something different, +@code{GPGME} will take no action. + +This means that if your application does not install any signal +handler for @code{SIGPIPE}, you don't need to take any precautions. +If you do install a signal handler for @code{SIGPIPE}, you must be +prepared to handle any @code{SIGPIPE} events that occur due to +@acronym{GPGME} writing to a defunct pipe. Furthermore, if your +application is multi-threaded, and you install a signal action for +@code{SIGPIPE}, you must make sure you do this either before +@code{gpgme_check_version} is called or afterwards. + + @node Multi Threading @section Multi Threading @cindex thread-safeness diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 18552f67..d2b82bd5 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,5 +1,10 @@ 2003-10-06 Marcus Brinkmann + * io.h (_gpgme_io_subsystem_init): New prototype. + * posix-io.c (_gpgme_io_subsystem_init): Add function. + (_gpgme_io_spawn): Do not fixup signal handler here. + * version.c (do_subsystem_inits): Call _gpgme_io_subsystem_init. + * debug.c (debug_init): Drop const qualifier from E. * ath.h (struct ath_ops): Make ADDR argument of CONNECT prototype diff --git a/gpgme/io.h b/gpgme/io.h index cb09969f..9cc5eb25 100644 --- a/gpgme/io.h +++ b/gpgme/io.h @@ -40,6 +40,7 @@ struct io_select_fd_s }; /* These function are either defined in posix-io.c or w32-io.c. */ +void _gpgme_io_subsystem_init (void); int _gpgme_io_read (int fd, void *buffer, size_t count); int _gpgme_io_write (int fd, const void *buffer, size_t count); int _gpgme_io_pipe (int filedes[2], int inherit_idx); diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c index 5034468d..5c9baaca 100644 --- a/gpgme/posix-io.c +++ b/gpgme/posix-io.c @@ -39,6 +39,23 @@ #include "ath.h" #include "debug.h" + +void +_gpgme_io_subsystem_init (void) +{ + struct sigaction act; + + sigaction (SIGPIPE, NULL, &act); + if (act.sa_handler == SIG_DFL) + { + act.sa_handler = SIG_IGN; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction (SIGPIPE, &act, NULL); + } +} + + static struct { void (*handler) (int,void*); @@ -162,27 +179,9 @@ _gpgme_io_spawn (const char *path, char **argv, struct spawn_fd_item_s *fd_child_list, struct spawn_fd_item_s *fd_parent_list) { - static int fixed_signals; - DEFINE_STATIC_LOCK (fixed_signals_lock); pid_t pid; int i; int status, signo; - LOCK (fixed_signals_lock); - if (!fixed_signals) - { - struct sigaction act; - - sigaction (SIGPIPE, NULL, &act); - if (act.sa_handler == SIG_DFL) - { - act.sa_handler = SIG_IGN; - sigemptyset (&act.sa_mask); - act.sa_flags = 0; - sigaction (SIGPIPE, &act, NULL); - } - fixed_signals = 1; - } - UNLOCK (fixed_signals_lock); pid = fork (); if (pid == -1) diff --git a/gpgme/version.c b/gpgme/version.c index d64e67a3..e2c4ef81 100644 --- a/gpgme/version.c +++ b/gpgme/version.c @@ -46,6 +46,8 @@ do_subsystem_inits (void) return; _gpgme_sema_subsystem_init (); + _gpgme_io_subsystem_init (); + done = 1; } diff --git a/tests/ChangeLog b/tests/ChangeLog index 01256675..e48dd6f2 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2003-10-06 Marcus Brinkmann + + * gpg/t-thread1.c (thread_one): Do not call initialize_gpgme. + Likewise. + 2003-09-14 Marcus Brinkmann * gpg/t-thread1.c (main): Call init_gpgme here. diff --git a/tests/gpg/t-thread1.c b/tests/gpg/t-thread1.c index 4c003b12..50549746 100644 --- a/tests/gpg/t-thread1.c +++ b/tests/gpg/t-thread1.c @@ -37,8 +37,6 @@ thread_one (void *name) { int i; - initialize_gpgme (); - for (i = 0; i < ROUNDS; i++) { gpgme_ctx_t ctx; @@ -89,7 +87,6 @@ void * thread_two (void *name) { int i; - initialize_gpgme (); const char *cipher_1_asc = make_filename ("cipher-1.asc"); char *agent_info; @@ -143,7 +140,7 @@ main (int argc, char *argv[]) init_gpgme (GPGME_PROTOCOL_OpenPGP); pthread_create (&tone, NULL, thread_one, "A"); - pthread_create (&ttwo, NULL, thread_two, "A"); + pthread_create (&ttwo, NULL, thread_two, "B"); pthread_join (tone, NULL); pthread_join (ttwo, NULL);