* assuan-io.c
** Don't try to support GNU Pth here.
+
+* assuan-pipe-connect.c
+** Do not install SIGPIPE signal handler here.
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];
if (!ctx || !name || !argv || !argv[0])
return ASSUAN_Invalid_Value;
+#ifndef _ASSUAN_IN_GPGME
if (!fixed_signals)
{
struct sigaction act;
fixed_signals = 1;
/* FIXME: This is not MT safe */
}
+#endif
if (pipe (rp) < 0)
return ASSUAN_General_Error;
+2003-10-06 Marcus Brinkmann <marcus@g10code.de>
+
+ * gpgme.texi (Signal Handling): New section.
+
2003-09-14 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Correct documentation on memory
* 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
* 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
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
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.
* ath.h (struct ath_ops): Make ADDR argument of CONNECT prototype
};
/* 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);
#include "ath.h"
#include "debug.h"
+\f
+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);
+ }
+}
+
+\f
static struct
{
void (*handler) (int,void*);
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)
return;
_gpgme_sema_subsystem_init ();
+ _gpgme_io_subsystem_init ();
+
done = 1;
}
+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>
* gpg/t-thread1.c (main): Call init_gpgme here.
{
int i;
- initialize_gpgme ();
-
for (i = 0; i < ROUNDS; i++)
{
gpgme_ctx_t ctx;
thread_two (void *name)
{
int i;
- initialize_gpgme ();
const char *cipher_1_asc = make_filename ("cipher-1.asc");
char *agent_info;
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);