/* POSIX compatible signal blocking.
   Copyright (C) 2008-2012 Free Software Foundation, Inc.
   Written by Eric Blake <ebb9@byu.net>, 2008.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <signal.h>

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>

/* This implementation of sigaction is tailored to native Windows behavior:
   signal() has SysV semantics (ie. the handler is uninstalled before
   it is invoked).  This is an inherent data race if an asynchronous
   signal is sent twice in a row before we can reinstall our handler,
   but there's nothing we can do about it.  Meanwhile, sigprocmask()
   is not present, and while we can use the gnulib replacement to
   provide critical sections, it too suffers from potential data races
   in the face of an ill-timed asynchronous signal.  And we compound
   the situation by reading static storage in a signal handler, which
   POSIX warns is not generically async-signal-safe.  Oh well.

   Additionally:
     - We don't implement SA_NOCLDSTOP or SA_NOCLDWAIT, because SIGCHLD
       is not defined.
     - We don't implement SA_ONSTACK, because sigaltstack() is not present.
     - We ignore SA_RESTART, because blocking native Windows API calls are
       not interrupted anyway when an asynchronous signal occurs, and the
       MSVCRT runtime never sets errno to EINTR.
     - We don't implement SA_SIGINFO because it is impossible to do so
       portably.

   POSIX states that an application should not mix signal() and
   sigaction().  We support the use of signal() within the gnulib
   sigprocmask() substitute, but all other application code linked
   with this module should stick with only sigaction().  */

/* Check some of our assumptions.  */
#if defined SIGCHLD || defined HAVE_SIGALTSTACK || defined HAVE_SIGINTERRUPT
# error "Revisit the assumptions made in the sigaction module"
#endif

/* Out-of-range substitutes make a good fallback for uncatchable
   signals.  */
#ifndef SIGKILL
# define SIGKILL (-1)
#endif
#ifndef SIGSTOP
# define SIGSTOP (-1)
#endif

/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
   for the signal SIGABRT.  Only one signal handler is stored for both
   SIGABRT and SIGABRT_COMPAT.  SIGABRT_COMPAT is not a signal of its own.  */
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# undef SIGABRT_COMPAT
# define SIGABRT_COMPAT 6
#endif

/* A signal handler.  */
typedef void (*handler_t) (int signal);

/* Set of current actions.  If sa_handler for an entry is NULL, then
   that signal is not currently handled by the sigaction handler.  */
static struct sigaction volatile action_array[NSIG] /* = 0 */;

/* Signal handler that is installed for signals.  */
static void
sigaction_handler (int sig)
{
  handler_t handler;
  sigset_t mask;
  sigset_t oldmask;
  int saved_errno = errno;
  if (sig < 0 || NSIG <= sig || !action_array[sig].sa_handler)
    {
      /* Unexpected situation; be careful to avoid recursive abort.  */
      if (sig == SIGABRT)
        signal (SIGABRT, SIG_DFL);
      abort ();
    }

  /* Reinstall the signal handler when required; otherwise update the
     bookkeeping so that the user's handler may call sigaction and get
     accurate results.  We know the signal isn't currently blocked, or
     we wouldn't be in its handler, therefore we know that we are not
     interrupting a sigaction() call.  There is a race where any
     asynchronous instance of the same signal occurring before we
     reinstall the handler will trigger the default handler; oh
     well.  */
  handler = action_array[sig].sa_handler;
  if ((action_array[sig].sa_flags & SA_RESETHAND) == 0)
    signal (sig, sigaction_handler);
  else
    action_array[sig].sa_handler = NULL;

  /* Block appropriate signals.  */
  mask = action_array[sig].sa_mask;
  if ((action_array[sig].sa_flags & SA_NODEFER) == 0)
    sigaddset (&mask, sig);
  sigprocmask (SIG_BLOCK, &mask, &oldmask);

  /* Invoke the user's handler, then restore prior mask.  */
  errno = saved_errno;
  handler (sig);
  saved_errno = errno;
  sigprocmask (SIG_SETMASK, &oldmask, NULL);
  errno = saved_errno;
}

/* Change and/or query the action that will be taken on delivery of
   signal SIG.  If not NULL, ACT describes the new behavior.  If not
   NULL, OACT is set to the prior behavior.  Return 0 on success, or
   set errno and return -1 on failure.  */
int
sigaction (int sig, const struct sigaction *restrict act,
           struct sigaction *restrict oact)
{
  sigset_t mask;
  sigset_t oldmask;
  int saved_errno;

  if (sig < 0 || NSIG <= sig || sig == SIGKILL || sig == SIGSTOP
      || (act && act->sa_handler == SIG_ERR))
    {
      errno = EINVAL;
      return -1;
    }

#ifdef SIGABRT_COMPAT
  if (sig == SIGABRT_COMPAT)
    sig = SIGABRT;
#endif

  /* POSIX requires sigaction() to be async-signal-safe.  In other
     words, if an asynchronous signal can occur while we are anywhere
     inside this function, the user's handler could then call
     sigaction() recursively and expect consistent results.  We meet
     this rule by using sigprocmask to block all signals before
     modifying any data structure that could be read from a signal
     handler; this works since we know that the gnulib sigprocmask
     replacement does not try to use sigaction() from its handler.  */
  if (!act && !oact)
    return 0;
  sigfillset (&mask);
  sigprocmask (SIG_BLOCK, &mask, &oldmask);
  if (oact)
    {
      if (action_array[sig].sa_handler)
        *oact = action_array[sig];
      else
        {
          /* Safe to change the handler at will here, since all
             signals are currently blocked.  */
          oact->sa_handler = signal (sig, SIG_DFL);
          if (oact->sa_handler == SIG_ERR)
            goto failure;
          signal (sig, oact->sa_handler);
          oact->sa_flags = SA_RESETHAND | SA_NODEFER;
          sigemptyset (&oact->sa_mask);
        }
    }

  if (act)
    {
      /* Safe to install the handler before updating action_array,
         since all signals are currently blocked.  */
      if (act->sa_handler == SIG_DFL || act->sa_handler == SIG_IGN)
        {
          if (signal (sig, act->sa_handler) == SIG_ERR)
            goto failure;
          action_array[sig].sa_handler = NULL;
        }
      else
        {
          if (signal (sig, sigaction_handler) == SIG_ERR)
            goto failure;
          action_array[sig] = *act;
        }
    }
  sigprocmask (SIG_SETMASK, &oldmask, NULL);
  return 0;

 failure:
  saved_errno = errno;
  sigprocmask (SIG_SETMASK, &oldmask, NULL);
  errno = saved_errno;
  return -1;
}
