Diff for /embedaddon/libiconv/srclib/sigprocmask.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2012/02/21 22:57:48 version 1.1.1.3, 2021/03/17 13:38:46
Line 1 Line 1
 /* POSIX compatible signal blocking.  /* POSIX compatible signal blocking.
   Copyright (C) 2006-2008 Free Software Foundation, Inc.   Copyright (C) 2006-2019 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2006.     Written by Bruno Haible <bruno@clisp.org>, 2006.
   
    This program is free software: you can redistribute it and/or modify     This program is free software: you can redistribute it and/or modify
Line 13 Line 13
    GNU General Public License for more details.     GNU General Public License for more details.
   
    You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
   
 #include <config.h>  #include <config.h>
   
Line 24 Line 24
 #include <stdint.h>  #include <stdint.h>
 #include <stdlib.h>  #include <stdlib.h>
   
   #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
   # include "msvc-inval.h"
   #endif
   
 /* We assume that a platform without POSIX signal blocking functions  /* We assume that a platform without POSIX signal blocking functions
    also does not have the POSIX sigaction() function, only the     also does not have the POSIX sigaction() function, only the
    signal() function.  We also assume signal() has SysV semantics,     signal() function.  We also assume signal() has SysV semantics,
    where any handler is uninstalled prior to being invoked.  This is     where any handler is uninstalled prior to being invoked.  This is
   true for Woe32 platforms.  */   true for native Windows platforms.  */
   
 /* We use raw signal(), but also provide a wrapper rpl_signal() so  /* We use raw signal(), but also provide a wrapper rpl_signal() so
    that applications can query or change a blocked signal.  */     that applications can query or change a blocked signal.  */
Line 46 Line 50
 /* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias  /* 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     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.  */     SIGABRT and SIGABRT_COMPAT.  SIGABRT_COMPAT is not a signal of its own.  */
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__#if defined _WIN32 && ! defined __CYGWIN__
 # undef SIGABRT_COMPAT  # undef SIGABRT_COMPAT
 # define SIGABRT_COMPAT 6  # define SIGABRT_COMPAT 6
 #endif  #endif
Line 58 Line 62
   
 typedef void (*handler_t) (int);  typedef void (*handler_t) (int);
   
   #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
   static handler_t
   signal_nothrow (int sig, handler_t handler)
   {
     handler_t result;
   
     TRY_MSVC_INVAL
       {
         result = signal (sig, handler);
       }
     CATCH_MSVC_INVAL
       {
         result = SIG_ERR;
         errno = EINVAL;
       }
     DONE_MSVC_INVAL;
   
     return result;
   }
   # define signal signal_nothrow
   #endif
   
 /* Handling of gnulib defined signals.  */  /* Handling of gnulib defined signals.  */
   
 #if GNULIB_defined_SIGPIPE  #if GNULIB_defined_SIGPIPE
Line 72  ext_signal (int sig, handler_t handler) Line 98  ext_signal (int sig, handler_t handler)
     {      {
     case SIGPIPE:      case SIGPIPE:
       {        {
        handler_t old_handler = SIGPIPE_handler;        handler_t old_handler = SIGPIPE_handler;
        SIGPIPE_handler = handler;        SIGPIPE_handler = handler;
        return old_handler;        return old_handler;
       }        }
     default: /* System defined signal */      default: /* System defined signal */
       return signal (sig, handler);        return signal (sig, handler);
     }      }
 }  }
   # undef signal
 # define signal ext_signal  # define signal ext_signal
 #endif  #endif
   
Line 90  sigismember (const sigset_t *set, int sig) Line 117  sigismember (const sigset_t *set, int sig)
     {      {
       #ifdef SIGABRT_COMPAT        #ifdef SIGABRT_COMPAT
       if (sig == SIGABRT_COMPAT)        if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;        sig = SIGABRT;
       #endif        #endif
   
       return (*set >> sig) & 1;        return (*set >> sig) & 1;
Line 113  sigaddset (sigset_t *set, int sig) Line 140  sigaddset (sigset_t *set, int sig)
     {      {
       #ifdef SIGABRT_COMPAT        #ifdef SIGABRT_COMPAT
       if (sig == SIGABRT_COMPAT)        if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;        sig = SIGABRT;
       #endif        #endif
   
       *set |= 1U << sig;        *set |= 1U << sig;
Line 133  sigdelset (sigset_t *set, int sig) Line 160  sigdelset (sigset_t *set, int sig)
     {      {
       #ifdef SIGABRT_COMPAT        #ifdef SIGABRT_COMPAT
       if (sig == SIGABRT_COMPAT)        if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;        sig = SIGABRT;
       #endif        #endif
   
       *set &= ~(1U << sig);        *set &= ~(1U << sig);
Line 204  sigprocmask (int operation, const sigset_t *set, sigse Line 231  sigprocmask (int operation, const sigset_t *set, sigse
       sigset_t to_block;        sigset_t to_block;
   
       switch (operation)        switch (operation)
        {        {
        case SIG_BLOCK:        case SIG_BLOCK:
          new_blocked_set = blocked_set | *set;          new_blocked_set = blocked_set | *set;
          break;          break;
        case SIG_SETMASK:        case SIG_SETMASK:
          new_blocked_set = *set;          new_blocked_set = *set;
          break;          break;
        case SIG_UNBLOCK:        case SIG_UNBLOCK:
          new_blocked_set = blocked_set & ~*set;          new_blocked_set = blocked_set & ~*set;
          break;          break;
        default:        default:
          errno = EINVAL;          errno = EINVAL;
          return -1;          return -1;
        }        }
       to_unblock = blocked_set & ~new_blocked_set;        to_unblock = blocked_set & ~new_blocked_set;
       to_block = new_blocked_set & ~blocked_set;        to_block = new_blocked_set & ~blocked_set;
   
       if (to_block != 0)        if (to_block != 0)
        {        {
          int sig;          int sig;
   
          for (sig = 0; sig < NSIG; sig++)          for (sig = 0; sig < NSIG; sig++)
            if ((to_block >> sig) & 1)            if ((to_block >> sig) & 1)
              {              {
                pending_array[sig] = 0;                pending_array[sig] = 0;
                if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)                if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
                  blocked_set |= 1U << sig;                  blocked_set |= 1U << sig;
              }              }
        }        }
   
       if (to_unblock != 0)        if (to_unblock != 0)
        {        {
          sig_atomic_t received[NSIG];          sig_atomic_t received[NSIG];
          int sig;          int sig;
   
          for (sig = 0; sig < NSIG; sig++)          for (sig = 0; sig < NSIG; sig++)
            if ((to_unblock >> sig) & 1)            if ((to_unblock >> sig) & 1)
              {              {
                if (signal (sig, old_handlers[sig]) != blocked_handler)                if (signal (sig, old_handlers[sig]) != blocked_handler)
                  /* The application changed a signal handler while the signal                  /* The application changed a signal handler while the signal
                     was blocked, bypassing our rpl_signal replacement.                     was blocked, bypassing our rpl_signal replacement.
                     We don't support this.  */                     We don't support this.  */
                  abort ();                  abort ();
                received[sig] = pending_array[sig];                received[sig] = pending_array[sig];
                blocked_set &= ~(1U << sig);                blocked_set &= ~(1U << sig);
                pending_array[sig] = 0;                pending_array[sig] = 0;
              }              }
            else            else
              received[sig] = 0;              received[sig] = 0;
   
          for (sig = 0; sig < NSIG; sig++)          for (sig = 0; sig < NSIG; sig++)
            if (received[sig])            if (received[sig])
              raise (sig);              raise (sig);
        }        }
     }      }
   return 0;    return 0;
 }  }
Line 274  rpl_signal (int sig, handler_t handler) Line 301  rpl_signal (int sig, handler_t handler)
     {      {
       #ifdef SIGABRT_COMPAT        #ifdef SIGABRT_COMPAT
       if (sig == SIGABRT_COMPAT)        if (sig == SIGABRT_COMPAT)
        sig = SIGABRT;        sig = SIGABRT;
       #endif        #endif
   
       if (blocked_set & (1U << sig))        if (blocked_set & (1U << sig))
        {        {
          /* POSIX states that sigprocmask and signal are both          /* POSIX states that sigprocmask and signal are both
             async-signal-safe.  This is not true of our             async-signal-safe.  This is not true of our
             implementation - there is a slight data race where an             implementation - there is a slight data race where an
             asynchronous interrupt on signal A can occur after we             asynchronous interrupt on signal A can occur after we
             install blocked_handler but before we have updated             install blocked_handler but before we have updated
             old_handlers for signal B, such that handler A can see             old_handlers for signal B, such that handler A can see
             stale information if it calls signal(B).  Oh well -             stale information if it calls signal(B).  Oh well -
             signal handlers really shouldn't try to manipulate the             signal handlers really shouldn't try to manipulate the
             installed handlers of unrelated signals.  */             installed handlers of unrelated signals.  */
          handler_t result = old_handlers[sig];          handler_t result = old_handlers[sig];
          old_handlers[sig] = handler;          old_handlers[sig] = handler;
          return result;          return result;
        }        }
       else        else
        return signal (sig, handler);        return signal (sig, handler);
     }      }
   else    else
     {      {
Line 303  rpl_signal (int sig, handler_t handler) Line 330  rpl_signal (int sig, handler_t handler)
 }  }
   
 #if GNULIB_defined_SIGPIPE  #if GNULIB_defined_SIGPIPE
/* Raise the signal SIG.  *//* Raise the signal SIGPIPE.  */
 int  int
rpl_raise (int sig)_gl_raise_SIGPIPE (void)
# undef raise 
 {  {
  switch (sig)  if (blocked_set & (1U << SIGPIPE))
     pending_array[SIGPIPE] = 1;
   else
     {      {
    case SIGPIPE:      handler_t handler = SIGPIPE_handler;
      if (blocked_set & (1U << sig))      if (handler == SIG_DFL)
        pending_array[sig] = 1;        exit (128 + SIGPIPE);
      else      else if (handler != SIG_IGN)
        {        (*handler) (SIGPIPE);
          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); 
     }      }
     return 0;
 }  }
 #endif  #endif

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>