X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Ffatal-signal.c;h=3862b797042a40cbbe3c3a53bf9696424b4373a3;hb=dd6ceef65e424d30db8706273f88c20b015012ce;hp=8718fd606deb0698bcd93b6ee67baab041a6f1d4;hpb=2220ef77b370b8a55591463e49d2789464f38aa5;p=gnulib.git diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c index 8718fd606..3862b7970 100644 --- a/lib/fatal-signal.c +++ b/lib/fatal-signal.c @@ -1,5 +1,5 @@ /* Emergency actions in case of a fatal signal. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003-2004, 2006-2007 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software; you can redistribute it and/or modify @@ -14,12 +14,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include /* Specification. */ #include "fatal-signal.h" @@ -27,10 +25,7 @@ #include #include #include -#include -#if HAVE_UNISTD_H -# include -#endif +#include #include "xalloc.h" @@ -54,7 +49,7 @@ plus SIGXCPU, SIGXFSZ - because they are quite similar to SIGTERM. */ -static const int fatal_signals[] = +static int fatal_signals[] = { /* ISO C 99 signals. */ #ifdef SIGINT @@ -77,11 +72,40 @@ static const int fatal_signals[] = #ifdef SIGXFSZ SIGXFSZ, #endif + /* Woe32 signals. */ +#ifdef SIGBREAK + SIGBREAK, +#endif 0 }; #define num_fatal_signals (SIZEOF (fatal_signals) - 1) +/* Eliminate signals whose signal handler is SIG_IGN. */ + +static void +init_fatal_signals (void) +{ + static bool fatal_signals_initialized = false; + if (!fatal_signals_initialized) + { +#if HAVE_SIGACTION + size_t i; + + for (i = 0; i < num_fatal_signals; i++) + { + struct sigaction action; + + if (sigaction (fatal_signals[i], NULL, &action) >= 0 + && action.sa_handler == SIG_IGN) + fatal_signals[i] = -1; + } +#endif + + fatal_signals_initialized = true; + } +} + /* ========================================================================= */ @@ -111,7 +135,8 @@ uninstall_handlers () size_t i; for (i = 0; i < num_fatal_signals; i++) - signal (fatal_signals[i], SIG_DFL); + if (fatal_signals[i] >= 0) + signal (fatal_signals[i], SIG_DFL); } @@ -153,7 +178,8 @@ install_handlers () size_t i; for (i = 0; i < num_fatal_signals; i++) - signal (fatal_signals[i], &fatal_signal_handler); + if (fatal_signals[i] >= 0) + signal (fatal_signals[i], &fatal_signal_handler); } @@ -165,6 +191,7 @@ at_fatal_signal (action_t action) static bool cleanup_initialized = false; if (!cleanup_initialized) { + init_fatal_signals (); install_handlers (); cleanup_initialized = true; } @@ -175,12 +202,17 @@ at_fatal_signal (action_t action) because then the cleanup() function could access an already deallocated array. */ actions_entry_t *old_actions = actions; + size_t old_actions_allocated = actions_allocated; size_t new_actions_allocated = 2 * actions_allocated; actions_entry_t *new_actions = - xmalloc (new_actions_allocated * sizeof (actions_entry_t)); - - memcpy (new_actions, old_actions, - actions_allocated * sizeof (actions_entry_t)); + XNMALLOC (new_actions_allocated, actions_entry_t); + size_t k; + + /* Don't use memcpy() here, because memcpy takes non-volatile arguments + and is therefore not guaranteed to complete all memory stores before + the next statement. */ + for (k = 0; k < old_actions_allocated; k++) + new_actions[k] = old_actions[k]; actions = new_actions; actions_allocated = new_actions_allocated; /* Now we can free the old actions array. */ @@ -199,8 +231,6 @@ at_fatal_signal (action_t action) /* ========================================================================= */ -#if HAVE_POSIX_SIGNALBLOCKING - static sigset_t fatal_signal_set; static void @@ -211,9 +241,12 @@ init_fatal_signal_set () { size_t i; + init_fatal_signals (); + sigemptyset (&fatal_signal_set); for (i = 0; i < num_fatal_signals; i++) - sigaddset (&fatal_signal_set, fatal_signals[i]); + if (fatal_signals[i] >= 0) + sigaddset (&fatal_signal_set, fatal_signals[i]); fatal_signal_set_initialized = true; } @@ -234,20 +267,3 @@ unblock_fatal_signals () init_fatal_signal_set (); sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); } - -#else - -/* Don't bother caring about the old systems which don't have POSIX signal - blocking. */ - -void -block_fatal_signals () -{ -} - -void -unblock_fatal_signals () -{ -} - -#endif