2003-10-06  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Signal Handling): New section.

gpgme/
2003-10-06  Marcus Brinkmann  <marcus@g10code.de>

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

tests/
2003-10-06  Marcus Brinkmann  <marcus@g10code.de>

	* gpg/t-thread1.c (thread_one): Do not call initialize_gpgme.
	Likewise.
This commit is contained in:
Marcus Brinkmann 2003-10-06 16:17:13 +00:00
parent 5024a533e8
commit 0d0378a200
10 changed files with 72 additions and 22 deletions

View File

@ -20,3 +20,6 @@ updating this directory, are:
* assuan-io.c * assuan-io.c
** Don't try to support GNU Pth here. ** Don't try to support GNU Pth here.
* assuan-pipe-connect.c
** Do not install SIGPIPE signal handler here.

View File

@ -102,7 +102,9 @@ AssuanError
assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
int *fd_child_list) int *fd_child_list)
{ {
#ifndef _ASSUAN_IN_GPGME
static int fixed_signals = 0; static int fixed_signals = 0;
#endif
AssuanError err; AssuanError err;
int rp[2]; int rp[2];
int wp[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]) if (!ctx || !name || !argv || !argv[0])
return ASSUAN_Invalid_Value; return ASSUAN_Invalid_Value;
#ifndef _ASSUAN_IN_GPGME
if (!fixed_signals) if (!fixed_signals)
{ {
struct sigaction act; struct sigaction act;
@ -125,6 +128,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
fixed_signals = 1; fixed_signals = 1;
/* FIXME: This is not MT safe */ /* FIXME: This is not MT safe */
} }
#endif
if (pipe (rp) < 0) if (pipe (rp) < 0)
return ASSUAN_General_Error; return ASSUAN_General_Error;

View File

@ -1,3 +1,7 @@
2003-10-06 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Signal Handling): New section.
2003-09-14 Marcus Brinkmann <marcus@g10code.de> 2003-09-14 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Correct documentation on memory * gpgme.texi (Multi Threading): Correct documentation on memory

View File

@ -107,6 +107,7 @@ Preparation
* Using Automake:: Compiler options to be used the easy way. * Using Automake:: Compiler options to be used the easy way.
* Using Libtool:: Avoiding compiler options entirely. * Using Libtool:: Avoiding compiler options entirely.
* Library Version Check:: Getting and verifying the library version. * 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. * Multi Threading:: How @acronym{GPGME} can be used in an MT environment.
Protocols and Engines Protocols and Engines
@ -322,6 +323,7 @@ of the library are verified.
* Using Automake:: Compiler options to be used the easy way. * Using Automake:: Compiler options to be used the easy way.
* Using Libtool:: Avoiding compiler options entirely. * Using Libtool:: Avoiding compiler options entirely.
* Library Version Check:: Getting and verifying the library version. * 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. * Multi Threading:: How @acronym{GPGME} can be used in an MT environment.
@end menu @end menu
@ -518,6 +520,34 @@ like this. @acronym{GPGME} can not do this for you because it would
not be thread safe. 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 @node Multi Threading
@section Multi Threading @section Multi Threading
@cindex thread-safeness @cindex thread-safeness

View File

@ -1,5 +1,10 @@
2003-10-06 Marcus Brinkmann <marcus@g10code.de> 2003-10-06 Marcus Brinkmann <marcus@g10code.de>
* 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. * debug.c (debug_init): Drop const qualifier from E.
* ath.h (struct ath_ops): Make ADDR argument of CONNECT prototype * ath.h (struct ath_ops): Make ADDR argument of CONNECT prototype

View File

@ -40,6 +40,7 @@ struct io_select_fd_s
}; };
/* These function are either defined in posix-io.c or w32-io.c. */ /* 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_read (int fd, void *buffer, size_t count);
int _gpgme_io_write (int fd, const 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); int _gpgme_io_pipe (int filedes[2], int inherit_idx);

View File

@ -39,6 +39,23 @@
#include "ath.h" #include "ath.h"
#include "debug.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 static struct
{ {
void (*handler) (int,void*); 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_child_list,
struct spawn_fd_item_s *fd_parent_list) struct spawn_fd_item_s *fd_parent_list)
{ {
static int fixed_signals;
DEFINE_STATIC_LOCK (fixed_signals_lock);
pid_t pid; pid_t pid;
int i; int i;
int status, signo; 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 (); pid = fork ();
if (pid == -1) if (pid == -1)

View File

@ -46,6 +46,8 @@ do_subsystem_inits (void)
return; return;
_gpgme_sema_subsystem_init (); _gpgme_sema_subsystem_init ();
_gpgme_io_subsystem_init ();
done = 1; done = 1;
} }

View File

@ -1,3 +1,8 @@
2003-10-06 Marcus Brinkmann <marcus@g10code.de>
* gpg/t-thread1.c (thread_one): Do not call initialize_gpgme.
Likewise.
2003-09-14 Marcus Brinkmann <marcus@g10code.de> 2003-09-14 Marcus Brinkmann <marcus@g10code.de>
* gpg/t-thread1.c (main): Call init_gpgme here. * gpg/t-thread1.c (main): Call init_gpgme here.

View File

@ -37,8 +37,6 @@ thread_one (void *name)
{ {
int i; int i;
initialize_gpgme ();
for (i = 0; i < ROUNDS; i++) for (i = 0; i < ROUNDS; i++)
{ {
gpgme_ctx_t ctx; gpgme_ctx_t ctx;
@ -89,7 +87,6 @@ void *
thread_two (void *name) thread_two (void *name)
{ {
int i; int i;
initialize_gpgme ();
const char *cipher_1_asc = make_filename ("cipher-1.asc"); const char *cipher_1_asc = make_filename ("cipher-1.asc");
char *agent_info; char *agent_info;
@ -143,7 +140,7 @@ main (int argc, char *argv[])
init_gpgme (GPGME_PROTOCOL_OpenPGP); init_gpgme (GPGME_PROTOCOL_OpenPGP);
pthread_create (&tone, NULL, thread_one, "A"); 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 (tone, NULL);
pthread_join (ttwo, NULL); pthread_join (ttwo, NULL);