From: Bruno Haible Date: Thu, 30 Nov 2006 13:25:57 +0000 (+0000) Subject: Guard against interruption with Ctrl-Z. X-Git-Tag: v0.17~619 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=73fe3b395ceae4b69f1fe626d584acaec723b6c8;p=thirdparty%2Fgettext.git Guard against interruption with Ctrl-Z. --- diff --git a/gnulib-local/ChangeLog b/gnulib-local/ChangeLog index a16d4cfb2..7ec42f392 100644 --- a/gnulib-local/ChangeLog +++ b/gnulib-local/ChangeLog @@ -1,3 +1,16 @@ +2006-11-28 Bruno Haible + + Guard against interruption with Ctrl-Z. + * lib/term-ostream.oo.c: Include also signal.h and sigprocmask.h. + (SIZEOF): New macro. + (stopping_signals): New variable. + (num_stopping_signals): New macro. + (stopping_signal_set): New variable. + (init_stopping_signal_set): New function. + (block_stopping_signals, unblock_stopping_signals): New functions. + (output_buffer): Use them. + * modules/term-ostream (Depends-on): Add sigprocmask. + 2006-11-28 Bruno Haible * lib/libcroco/cr-fonts.h: Fix double-inclusion guard. diff --git a/gnulib-local/lib/term-ostream.oo.c b/gnulib-local/lib/term-ostream.oo.c index 5482ce740..5240bfcca 100644 --- a/gnulib-local/lib/term-ostream.oo.c +++ b/gnulib-local/lib/term-ostream.oo.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -31,12 +32,15 @@ #include "exit.h" #include "fatal-signal.h" #include "full-write.h" +#include "sigprocmask.h" #include "xalloc.h" #include "xsize.h" #include "gettext.h" #define _(str) gettext (str) +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + /* Including or is dangerous, because it also declares a lot of junk, such as variables PC, UP, and other. */ @@ -219,6 +223,57 @@ restore (void) } } +/* The list of signals whose default behaviour is to stop the program. */ +static int stopping_signals[] = + { +#ifdef SIGTSTP + SIGTSTP, +#endif +#ifdef SIGTTIN + SIGTTIN, +#endif +#ifdef SIGTTOU + SIGTTOU, +#endif + 0 + }; + +#define num_stopping_signals (SIZEOF (stopping_signals) - 1) + +static sigset_t stopping_signal_set; + +static void +init_stopping_signal_set () +{ + static bool stopping_signal_set_initialized = false; + if (!stopping_signal_set_initialized) + { + size_t i; + + sigemptyset (&stopping_signal_set); + for (i = 0; i < num_stopping_signals; i++) + sigaddset (&stopping_signal_set, stopping_signals[i]); + + stopping_signal_set_initialized = true; + } +} + +/* Temporarily delay the stopping signals. */ +void +block_stopping_signals () +{ + init_stopping_signal_set (); + sigprocmask (SIG_BLOCK, &stopping_signal_set, NULL); +} + +/* Stop delaying the stopping signals. */ +void +unblock_stopping_signals () +{ + init_stopping_signal_set (); + sigprocmask (SIG_UNBLOCK, &stopping_signal_set, NULL); +} + /* Compare two sets of attributes for equality. */ static inline bool equal_attributes (attributes_t attr1, attributes_t attr2) @@ -379,6 +434,8 @@ output_buffer (term_ostream_t stream) /* Block fatal signals, so that a SIGINT or similar doesn't interrupt us without the possibility of restoring the terminal's state. */ block_fatal_signals (); + /* Likewise for SIGTSTP etc. */ + block_stopping_signals (); /* Enable the exit handler for restoring the terminal's state. */ restore_colors = @@ -426,7 +483,8 @@ output_buffer (term_ostream_t stream) out_fd = -1; out_filename = NULL; - /* Unblock fatal signals. */ + /* Unblock fatal and stopping signals. */ + unblock_stopping_signals (); unblock_fatal_signals (); } stream->buflen = 0; diff --git a/gnulib-local/modules/term-ostream b/gnulib-local/modules/term-ostream index 24fdf6818..00fafb1c3 100644 --- a/gnulib-local/modules/term-ostream +++ b/gnulib-local/modules/term-ostream @@ -11,6 +11,7 @@ ostream error exit fatal-signal +sigprocmask full-write gettext-h termcap