diff options
author | Bruno Haible <bruno@clisp.org> | 2006-11-30 13:25:57 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:14:25 +0200 |
commit | 73fe3b395ceae4b69f1fe626d584acaec723b6c8 (patch) | |
tree | 2c3940d427f4867c64b1fd9f78487057956d2b8e /gnulib-local/lib | |
parent | cbea8c5f3c584806e6ba97d8ef86e641222b79f4 (diff) | |
download | external_gettext-73fe3b395ceae4b69f1fe626d584acaec723b6c8.zip external_gettext-73fe3b395ceae4b69f1fe626d584acaec723b6c8.tar.gz external_gettext-73fe3b395ceae4b69f1fe626d584acaec723b6c8.tar.bz2 |
Guard against interruption with Ctrl-Z.
Diffstat (limited to 'gnulib-local/lib')
-rw-r--r-- | gnulib-local/lib/term-ostream.oo.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/gnulib-local/lib/term-ostream.oo.c b/gnulib-local/lib/term-ostream.oo.c index 5482ce7..5240bfc 100644 --- a/gnulib-local/lib/term-ostream.oo.c +++ b/gnulib-local/lib/term-ostream.oo.c @@ -23,6 +23,7 @@ #include <assert.h> #include <errno.h> +#include <signal.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> @@ -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 <curses.h> or <term.h> 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; |