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

version 1.1.1.1, 2012/02/21 22:57:48 version 1.1.1.2, 2012/05/29 09:29:43
Line 1 Line 1
 /* POSIX compatible signal blocking.  /* POSIX compatible signal blocking.
   Copyright (C) 2006-2008 Free Software Foundation, Inc.   Copyright (C) 2006-2011 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 72  ext_signal (int sig, handler_t handler) Line 72  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);
Line 90  sigismember (const sigset_t *set, int sig) Line 90  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 113  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 133  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 204  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 274  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 312  rpl_raise (int sig) Line 312  rpl_raise (int sig)
     {      {
     case SIGPIPE:      case SIGPIPE:
       if (blocked_set & (1U << sig))        if (blocked_set & (1U << sig))
        pending_array[sig] = 1;        pending_array[sig] = 1;
       else        else
        {        {
          handler_t handler = SIGPIPE_handler;          handler_t handler = SIGPIPE_handler;
          if (handler == SIG_DFL)          if (handler == SIG_DFL)
            exit (128 + SIGPIPE);            exit (128 + SIGPIPE);
          else if (handler != SIG_IGN)          else if (handler != SIG_IGN)
            (*handler) (sig);            (*handler) (sig);
        }        }
       return 0;        return 0;
     default: /* System defined signal */      default: /* System defined signal */
       return raise (sig);        return raise (sig);

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


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