Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/lib/posix/signal/__exception.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __sig_flush
  2. __exception_handler
  3. __exception_init
  4. __exception_exit

   1 /*
   2  * Copyright (c) 2005-2009, Kohsuke Ohtani
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the author nor the names of any co-contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 #include <sys/prex.h>
  31 #include <sys/signal.h>
  32 
  33 #include <unistd.h>
  34 #include <signal.h>
  35 #include <stdlib.h>
  36 
  37 void __exception_init(void);
  38 void __exception_exit(int *);
  39 
  40 static int __sig_exit;
  41 
  42 struct sigaction __sig_act[NSIG];
  43 sigset_t __sig_mask;
  44 sigset_t __sig_pending;
  45 
  46 #ifdef _REENTRANT
  47 volatile mutex_t __sig_lock;
  48 #endif
  49 
  50 /*
  51  * Process all pending and unmasked signal
  52  *
  53  * return 0 if at least one pending signal was processed.
  54  * return -1 if no signal was processed.
  55  */
  56 int
  57 __sig_flush(void)
  58 {
  59         int sig;
  60         sigset_t active, org_mask;
  61         struct sigaction action;
  62         struct siginfo si;
  63         int rc = -1;
  64 
  65         sig = 1;
  66         for (;;) {
  67                 SIGNAL_LOCK();
  68                 active = __sig_pending & ~__sig_mask;
  69                 action = __sig_act[sig];
  70                 SIGNAL_UNLOCK();
  71 
  72                 if (active == 0)
  73                         break;
  74                 if (active & sigmask(sig)) {
  75 
  76                         SIGNAL_LOCK();
  77                         org_mask = __sig_mask;
  78                         __sig_mask |= action.sa_mask;
  79                         SIGNAL_UNLOCK();
  80 
  81                         if (action.sa_handler == SIG_DFL) {
  82                                 /* Default */
  83                                 switch (sig) {
  84                                 case SIGCHLD:
  85                                 case SIGTSTP:
  86                                         /* XXX: */
  87                                         break;
  88                                 default:
  89                                         SIGNAL_LOCK();
  90                                         __sig_pending &= ~sigmask(sig);
  91                                         __sig_mask = org_mask;
  92                                         __sig_exit = sig;
  93                                         SIGNAL_UNLOCK();
  94                                         exit(0);
  95                                 }
  96                         } else if (action.sa_handler != SIG_IGN) {
  97                                 /* User defined */
  98                                 if (action.sa_flags & SA_SIGINFO) {
  99                                         si.si_signo = sig;
 100                                         si.si_code = 0;
 101                                         si.si_value.sival_int = 0;
 102                                         action.sa_sigaction(sig, &si, NULL);
 103                                 } else {
 104                                         action.sa_handler(sig);
 105                                 }
 106                         }
 107                         SIGNAL_LOCK();
 108                         __sig_pending &= ~sigmask(sig);
 109                         __sig_mask = org_mask;
 110                         SIGNAL_UNLOCK();
 111 
 112                         switch (sig) {
 113                         case SIGILL:
 114                         case SIGTRAP:
 115                         case SIGFPE:
 116                         case SIGSEGV:
 117                                 for (;;);       /* exception from kernel */
 118                                 break;
 119                         }
 120                         if (action.sa_handler != SIG_IGN)
 121                                 rc = 0; /* Signal is processed */
 122                 }
 123 
 124                 if (++sig >= NSIG)
 125                         sig = 1;
 126         }
 127         return rc;
 128 }
 129 
 130 /*
 131  * Exception handler for signal emulation
 132  */
 133 static void
 134 __exception_handler(int excpt)
 135 {
 136 
 137         if (excpt > 0 && excpt <= NSIG) {
 138 
 139                 SIGNAL_LOCK();
 140 
 141                 if (__sig_act[excpt].sa_handler != SIG_IGN)
 142                         __sig_pending |= sigmask(excpt);
 143 
 144                 SIGNAL_UNLOCK();
 145         }
 146         __sig_flush();
 147         exception_return();
 148 }
 149 
 150 /*
 151  * Initialize exception
 152  */
 153 void
 154 __exception_init(void)
 155 {
 156         int i;
 157 
 158 #ifdef _REENTRANT
 159         mutex_init(&__sig_lock);
 160 #endif
 161         exception_setup(EXC_DFL);
 162 
 163         __sig_mask = 0;
 164         __sig_pending = 0;
 165         __sig_exit = 0;
 166 
 167         for (i = 0; i < NSIG; i++) {
 168                 __sig_act[i].sa_flags = 0;
 169                 __sig_act[i].sa_handler = SIG_DFL;
 170         }
 171 
 172         /* Install exception handler */
 173         exception_setup(__exception_handler);
 174 }
 175 
 176 /*
 177  * Clean up
 178  */
 179 void
 180 __exception_exit(int *signo)
 181 {
 182 
 183 #ifdef _REENTRANT
 184         mutex_destroy(&__sig_lock);
 185 #endif
 186         exception_setup(EXC_DFL);
 187 
 188         *signo = __sig_exit;
 189         __sig_exit = 0;
 190         __sig_pending = 0;
 191 }

/* [<][>][^][v][top][bottom][index][help] */