105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Emergency actions in case of a fatal signal.
205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Copyright (C) 2003-2004, 2006-2012 Free Software Foundation, Inc.
305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Written by Bruno Haible <bruno@clisp.org>, 2003.
405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is free software: you can redistribute it and/or modify
605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   it under the terms of the GNU General Public License as published by
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the Free Software Foundation; either version 3 of the License, or
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (at your option) any later version.
905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is distributed in the hope that it will be useful,
1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   but WITHOUT ANY WARRANTY; without even the implied warranty of
1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   GNU General Public License for more details.
1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   You should have received a copy of the GNU General Public License
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h>
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Specification.  */
2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "fatal-signal.h"
2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdbool.h>
2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdlib.h>
2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <signal.h>
2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <unistd.h>
2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "sig-handler.h"
3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "xalloc.h"
3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The list of fatal signals.
3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   These are those signals whose default action is to terminate the process
3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   without a core dump, except
4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGKILL - because it cannot be caught,
4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGALRM SIGUSR1 SIGUSR2 SIGPOLL SIGIO SIGLOST - because applications
4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang       often use them for their own purpose,
4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGPROF SIGVTALRM - because they are used for profiling,
4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGSTKFLT - because it is more similar to SIGFPE, SIGSEGV, SIGBUS,
4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGSYS - because it is more similar to SIGABRT, SIGSEGV,
4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGPWR - because it of too special use,
4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGRTMIN...SIGRTMAX - because they are reserved for application use.
4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   plus
4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SIGXCPU, SIGXFSZ - because they are quite similar to SIGTERM.  */
5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int fatal_signals[] =
5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  {
5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    /* ISO C 99 signals.  */
5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGINT
5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGINT,
5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGTERM
5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGTERM,
5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    /* POSIX:2001 signals.  */
6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGHUP
6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGHUP,
6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGPIPE
6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGPIPE,
6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    /* BSD signals.  */
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGXCPU
6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGXCPU,
7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGXFSZ
7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGXFSZ,
7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    /* Native Windows signals.  */
7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifdef SIGBREAK
7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    SIGBREAK,
7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    0
7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  };
8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define num_fatal_signals (SIZEOF (fatal_signals) - 1)
8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Eliminate signals whose signal handler is SIG_IGN.  */
8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
8605436638acc7c010349a69c3395f1a57c642dc62Ying Wanginit_fatal_signals (void)
8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  static bool fatal_signals_initialized = false;
8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!fatal_signals_initialized)
9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t i;
9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      for (i = 0; i < num_fatal_signals; i++)
9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          struct sigaction action;
9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (sigaction (fatal_signals[i], NULL, &action) >= 0
9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              && get_handler (&action) == SIG_IGN)
9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang            fatal_signals[i] = -1;
10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      fatal_signals_initialized = true;
10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
11005436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef void (*action_t) (void);
11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Type of an entry in the actions array.
11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   The 'action' field is accessed from within the fatal_signal_handler(),
11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   therefore we mark it as 'volatile'.  */
11505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  volatile action_t action;
11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
11905436638acc7c010349a69c3395f1a57c642dc62Ying Wangactions_entry_t;
12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The registered cleanup actions.  */
12205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic actions_entry_t static_actions[32];
12305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic actions_entry_t * volatile actions = static_actions;
12405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic sig_atomic_t volatile actions_count = 0;
12505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic size_t actions_allocated = SIZEOF (static_actions);
12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The saved signal handlers.
12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Size 32 would not be sufficient: On HP-UX, SIGXCPU = 33, SIGXFSZ = 34.  */
13005436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic struct sigaction saved_sigactions[64];
13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Uninstall the handlers.  */
13405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
13505436638acc7c010349a69c3395f1a57c642dc62Ying Wanguninstall_handlers (void)
13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  size_t i;
13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (i = 0; i < num_fatal_signals; i++)
14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (fatal_signals[i] >= 0)
14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        int sig = fatal_signals[i];
14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (saved_sigactions[sig].sa_handler == SIG_IGN)
14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          saved_sigactions[sig].sa_handler = SIG_DFL;
14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        sigaction (sig, &saved_sigactions[sig], NULL);
14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The signal handler.  It gets called asynchronously.  */
15105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
15205436638acc7c010349a69c3395f1a57c642dc62Ying Wangfatal_signal_handler (int sig)
15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (;;)
15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Get the last registered cleanup action, in a reentrant way.  */
15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      action_t action;
15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t n = actions_count;
15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (n == 0)
16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        break;
16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      n--;
16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      actions_count = n;
16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      action = actions[n].action;
16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Execute the action.  */
16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      action ();
16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Now execute the signal's default action.
16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     If the signal being delivered was blocked, the re-raised signal would be
17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     delivered when this handler returns.  But the way we install this handler,
17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     no signal is blocked, and the re-raised signal is delivered already
17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     during raise().  */
17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  uninstall_handlers ();
17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  raise (sig);
17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
17605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
17705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
17805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Install the handlers.  */
17905436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
18005436638acc7c010349a69c3395f1a57c642dc62Ying Wanginstall_handlers (void)
18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  size_t i;
18305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  struct sigaction action;
18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
18505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  action.sa_handler = &fatal_signal_handler;
18605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* If we get a fatal signal while executing fatal_signal_handler, enter
18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     fatal_signal_handler recursively, since it is reentrant.  Hence no
18805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     SA_RESETHAND.  */
18905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  action.sa_flags = SA_NODEFER;
19005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  sigemptyset (&action.sa_mask);
19105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  for (i = 0; i < num_fatal_signals; i++)
19205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    if (fatal_signals[i] >= 0)
19305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      {
19405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        int sig = fatal_signals[i];
19505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
19605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (!(sig < sizeof (saved_sigactions) / sizeof (saved_sigactions[0])))
19705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          abort ();
19805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        sigaction (sig, &action, &saved_sigactions[sig]);
19905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      }
20005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
20105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
20205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
20305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Register a cleanup function to be executed when a catchable fatal signal
20405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   occurs.  */
20505436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
20605436638acc7c010349a69c3395f1a57c642dc62Ying Wangat_fatal_signal (action_t action)
20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  static bool cleanup_initialized = false;
20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!cleanup_initialized)
21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      init_fatal_signals ();
21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      install_handlers ();
21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      cleanup_initialized = true;
21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (actions_count == actions_allocated)
21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Extend the actions array.  Note that we cannot use xrealloc(),
21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang         because then the cleanup() function could access an already
22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang         deallocated array.  */
22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      actions_entry_t *old_actions = actions;
22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t old_actions_allocated = actions_allocated;
22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t new_actions_allocated = 2 * actions_allocated;
22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      actions_entry_t *new_actions =
22505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        XNMALLOC (new_actions_allocated, actions_entry_t);
22605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t k;
22705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
22805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Don't use memcpy() here, because memcpy takes non-volatile arguments
22905436638acc7c010349a69c3395f1a57c642dc62Ying Wang         and is therefore not guaranteed to complete all memory stores before
23005436638acc7c010349a69c3395f1a57c642dc62Ying Wang         the next statement.  */
23105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      for (k = 0; k < old_actions_allocated; k++)
23205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        new_actions[k] = old_actions[k];
23305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      actions = new_actions;
23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      actions_allocated = new_actions_allocated;
23505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      /* Now we can free the old actions array.  */
23605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (old_actions != static_actions)
23705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        free (old_actions);
23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* The two uses of 'volatile' in the types above (and ISO C 99 section
24005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     5.1.2.3.(5)) ensure that we increment the actions_count only after
24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     the new action has been written to the memory location
24205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     actions[actions_count].  */
24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  actions[actions_count].action = action;
24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  actions_count++;
24505436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
24605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
24805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
24905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
25005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
25105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic sigset_t fatal_signal_set;
25205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
25305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
25405436638acc7c010349a69c3395f1a57c642dc62Ying Wanginit_fatal_signal_set (void)
25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
25605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  static bool fatal_signal_set_initialized = false;
25705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (!fatal_signal_set_initialized)
25805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    {
25905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t i;
26005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      init_fatal_signals ();
26205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      sigemptyset (&fatal_signal_set);
26405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      for (i = 0; i < num_fatal_signals; i++)
26505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        if (fatal_signals[i] >= 0)
26605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          sigaddset (&fatal_signal_set, fatal_signals[i]);
26705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      fatal_signal_set_initialized = true;
26905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    }
27005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
27205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Temporarily delay the catchable fatal signals.  */
27305436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
27405436638acc7c010349a69c3395f1a57c642dc62Ying Wangblock_fatal_signals (void)
27505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
27605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  init_fatal_signal_set ();
27705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
27805436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
27905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
28005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Stop delaying the catchable fatal signals.  */
28105436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid
28205436638acc7c010349a69c3395f1a57c642dc62Ying Wangunblock_fatal_signals (void)
28305436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
28405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  init_fatal_signal_set ();
28505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
287