/* POSIX compatible signal blocking.
   Copyright (C) 2006-2011 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2006.

   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>

/* We assume that a platform without POSIX signal blocking functions
   also does not have the POSIX sigaction() function, only the
   signal() function.  We also assume signal() has SysV semantics,
   where any handler is uninstalled prior to being invoked.  This is
   true for Woe32 platforms.  */

/* We use raw signal(), but also provide a wrapper rpl_signal() so
   that applications can query or change a blocked signal.  */
#undef signal

/* Provide invalid signal numbers as fallbacks if the uncatchable
   signals are not defined.  */
#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
#ifdef SIGABRT_COMPAT
# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT)
#else
# define SIGABRT_COMPAT_MASK 0
#endif

typedef void (*handler_t) (int);

/* Handling of gnulib defined signals.  */

#if GNULIB_defined_SIGPIPE
static handler_t SIGPIPE_handler = SIG_DFL;
#endif

#if GNULIB_defined_SIGPIPE
static handler_t
ext_signal (int sig, handler_t handler)
{
  switch (sig)
    {
    case SIGPIPE:
      {
        handler_t old_handler = SIGPIPE_handler;
        SIGPIPE_handler = handler;
        return old_handler;
      }
    default: /* System defined signal */
      return signal (sig, handler);
    }
}
# define signal ext_signal
#endif

int
sigismember (const sigset_t *set, int sig)
{
  if (sig >= 0 && sig < NSIG)
    {
      #ifdef SIGABRT_COMPAT
      if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;
      #endif

      return (*set >> sig) & 1;
    }
  else
    return 0;
}

int
sigemptyset (sigset_t *set)
{
  *set = 0;
  return 0;
}

int
sigaddset (sigset_t *set, int sig)
{
  if (sig >= 0 && sig < NSIG)
    {
      #ifdef SIGABRT_COMPAT
      if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;
      #endif

      *set |= 1U << sig;
      return 0;
    }
  else
    {
      errno = EINVAL;
      return -1;
    }
}

int
sigdelset (sigset_t *set, int sig)
{
  if (sig >= 0 && sig < NSIG)
    {
      #ifdef SIGABRT_COMPAT
      if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;
      #endif

      *set &= ~(1U << sig);
      return 0;
    }
  else
    {
      errno = EINVAL;
      return -1;
    }
}


int
sigfillset (sigset_t *set)
{
  *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
  return 0;
}

/* Set of currently blocked signals.  */
static volatile sigset_t blocked_set /* = 0 */;

/* Set of currently blocked and pending signals.  */
static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;

/* Signal handler that is installed for blocked signals.  */
static void
blocked_handler (int sig)
{
  /* Reinstall the handler, in case the signal occurs multiple times
     while blocked.  There is an inherent race where an asynchronous
     signal in between when the kernel uninstalled the handler and
     when we reinstall it will trigger the default handler; oh
     well.  */
  signal (sig, blocked_handler);
  if (sig >= 0 && sig < NSIG)
    pending_array[sig] = 1;
}

int
sigpending (sigset_t *set)
{
  sigset_t pending = 0;
  int sig;

  for (sig = 0; sig < NSIG; sig++)
    if (pending_array[sig])
      pending |= 1U << sig;
  *set = pending;
  return 0;
}

/* The previous signal handlers.
   Only the array elements corresponding to blocked signals are relevant.  */
static volatile handler_t old_handlers[NSIG];

int
sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
{
  if (old_set != NULL)
    *old_set = blocked_set;

  if (set != NULL)
    {
      sigset_t new_blocked_set;
      sigset_t to_unblock;
      sigset_t to_block;

      switch (operation)
        {
        case SIG_BLOCK:
          new_blocked_set = blocked_set | *set;
          break;
        case SIG_SETMASK:
          new_blocked_set = *set;
          break;
        case SIG_UNBLOCK:
          new_blocked_set = blocked_set & ~*set;
          break;
        default:
          errno = EINVAL;
          return -1;
        }
      to_unblock = blocked_set & ~new_blocked_set;
      to_block = new_blocked_set & ~blocked_set;

      if (to_block != 0)
        {
          int sig;

          for (sig = 0; sig < NSIG; sig++)
            if ((to_block >> sig) & 1)
              {
                pending_array[sig] = 0;
                if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
                  blocked_set |= 1U << sig;
              }
        }

      if (to_unblock != 0)
        {
          sig_atomic_t received[NSIG];
          int sig;

          for (sig = 0; sig < NSIG; sig++)
            if ((to_unblock >> sig) & 1)
              {
                if (signal (sig, old_handlers[sig]) != blocked_handler)
                  /* The application changed a signal handler while the signal
                     was blocked, bypassing our rpl_signal replacement.
                     We don't support this.  */
                  abort ();
                received[sig] = pending_array[sig];
                blocked_set &= ~(1U << sig);
                pending_array[sig] = 0;
              }
            else
              received[sig] = 0;

          for (sig = 0; sig < NSIG; sig++)
            if (received[sig])
              raise (sig);
        }
    }
  return 0;
}

/* Install the handler FUNC for signal SIG, and return the previous
   handler.  */
handler_t
rpl_signal (int sig, handler_t handler)
{
  /* We must provide a wrapper, so that a user can query what handler
     they installed even if that signal is currently blocked.  */
  if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
      && handler != SIG_ERR)
    {
      #ifdef SIGABRT_COMPAT
      if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;
      #endif

      if (blocked_set & (1U << sig))
        {
          /* POSIX states that sigprocmask and signal are both
             async-signal-safe.  This is not true of our
             implementation - there is a slight data race where an
             asynchronous interrupt on signal A can occur after we
             install blocked_handler but before we have updated
             old_handlers for signal B, such that handler A can see
             stale information if it calls signal(B).  Oh well -
             signal handlers really shouldn't try to manipulate the
             installed handlers of unrelated signals.  */
          handler_t result = old_handlers[sig];
          old_handlers[sig] = handler;
          return result;
        }
      else
        return signal (sig, handler);
    }
  else
    {
      errno = EINVAL;
      return SIG_ERR;
    }
}

#if GNULIB_defined_SIGPIPE
/* Raise the signal SIG.  */
int
rpl_raise (int sig)
# undef raise
{
  switch (sig)
    {
    case SIGPIPE:
      if (blocked_set & (1U << sig))
        pending_array[sig] = 1;
      else
        {
          handler_t handler = SIGPIPE_handler;
          if (handler == SIG_DFL)
            exit (128 + SIGPIPE);
          else if (handler != SIG_IGN)
            (*handler) (sig);
        }
      return 0;
    default: /* System defined signal */
      return raise (sig);
    }
}
#endif
