/[ascend]/trunk/base/generic/utilities/ascSignal.c
ViewVC logotype

Diff of /trunk/base/generic/utilities/ascSignal.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 952 by johnpye, Fri Aug 4 05:54:34 2006 UTC revision 953 by johnpye, Thu Dec 7 14:47:15 2006 UTC
# Line 16  Line 16 
16      along with this program; if not, write to the Free Software      along with this program; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place - Suite 330,      Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.      Boston, MA 02111-1307, USA.
19  *//**  *//** @file
20   * Signal handling protocol definitions for ASCEND      Signal handling protocol definitions for ASCEND
21   * Start of making signal handling in ASCEND  
22   * code somewhat sane. Still needs to somehow      Start of making signal handling in ASCEND
23   * support the management of jmp_buf's so that      code somewhat sane. Still needs to somehow
24   * handlers will longjmp to the right place.      support the management of jmp_buf's so that
25   *      handlers will longjmp to the right place.
26   * A better alternative is to make all our code check/return  
27   * status flags based on a variable set by the trap      A better alternative is to make all our code check/return
28   * and cleared by recipient.      status flags based on a variable set by the trap
29        and cleared by recipient.
30  *//*  *//*
31   *  May 27, 1997      by Benjamin Andrew Allan, May 27, 1997
32   *  By Benjamin Andrew Allan      Last in CVS $Revision: 1.9 $ $Date: 1999/01/19 12:23:20 $ $Author: mthomas $
33   *  Version: $Revision: 1.9 $      
34   *  Version control file: $RCSfile: ascSignal.c,v $      ChangeLog
35   *  Date last modified: $Date: 1999/01/19 12:23:20 $  
36   *  Last modified by: $Author: mthomas $      10/15/2005  - Changed ascresetneeded() so that any previously
37   *                    registered handlers are reset before return.
38   *  ChangeLog                  - Added Asc_SignalRecover() to standard handler
39   *                    Asc_SignalTrap() so handlers are reset if necessary. (JDS)
40   *  10/15/2005  - Changed ascresetneeded() so that any previously      12/10/2005  - Changed storage of signal handlers from gl_list's
41   *                registered handlers are reset before return.                    to local arrays.  gl_list's can't legally hold
42   *              - Added Asc_SignalRecover() to standard handler                    function pointers. (JDS)
43   *                Asc_SignalTrap() so handlers are reset if necessary. (JDS)  */
  *  12/10/2005  - Changed storage of signal handlers from gl_list's  
  *                to local arrays.  gl_list's can't legally hold  
  *                function pointers. (JDS)  
  */  
44    
45  #include <stdio.h>  #include <stdio.h>
46  #include "ascConfig.h"  #include "ascConfig.h"
# Line 82  static int f_reset_needed = -2; Line 79  static int f_reset_needed = -2;
79   * and if Init is called without the value -2 in f_reset_needed,   * and if Init is called without the value -2 in f_reset_needed,
80   * it will fail.   * it will fail.
81   */   */
82  static SigHandler *f_fpe_traps = NULL;  /**< array for pushed SIGFPE handlers */  static SigHandlerFn **f_fpe_traps = NULL;  /**< array for pushed SIGFPE handlers */
83  static int f_fpe_top_of_stack = -1;     /**< top of SIGFPE stack, -1 for empty */  static int f_fpe_top_of_stack = -1;     /**< top of SIGFPE stack, -1 for empty */
84    
85  static SigHandler *f_int_traps = NULL;  /**< array for pushed SIGINT handlers */  static SigHandlerFn **f_int_traps = NULL;  /**< array for pushed SIGINT handlers */
86  static int f_int_top_of_stack = -1;     /**< top of SIGFPE stack, -1 for empty */  static int f_int_top_of_stack = -1;     /**< top of SIGFPE stack, -1 for empty */
87    
88  static SigHandler *f_seg_traps = NULL;  /**< array for pushed SIGSEGV handlers */  static SigHandlerFn **f_seg_traps = NULL;  /**< array for pushed SIGSEGV handlers */
89  static int f_seg_top_of_stack = -1;     /**< top of SIGFPE stack, -1 for empty */  static int f_seg_top_of_stack = -1;     /**< top of SIGFPE stack, -1 for empty */
90    
91  #ifndef NO_SIGSEGV_TRAP  #ifndef NO_SIGSEGV_TRAP
# Line 125  static void testcatch(int signum){ Line 122  static void testcatch(int signum){
122   * OSF32 cc   * OSF32 cc
123   * NetBSD gcc 2.4.5 -ansi   * NetBSD gcc 2.4.5 -ansi
124   */   */
125  /* This function tests the signal reseting of compilers using SIGINT.  
126   * It should not be called except when starting a process.  /**
127   * Return 0 for no reset needed, 1 for reset needed, and      This function tests the signal reseting of compilers using SIGINT.
128   * -1 if the test fails (presuming program doesn't exit first.)      It should not be called except when starting a process.
129   * Side effects:  
130   *   - a line is sent to ASCERR      Side effects:
131   *   - SIGINT is set to SIG_DFL if no handler was previously registered       - a line is sent to ASCERR
132   *   - SIGFPE may be set to SIG_DFL if no handler was previously registered       - SIGINT is set to SIG_DFL if no handler was previously registered
133   */       - SIGFPE may be set to SIG_DFL if no handler was previously registered
134    
135        @return 0 for no reset needed, 1 for reset needed, and
136        -1 if the test fails (presuming program doesn't exit first.)
137    */
138  static int ascresetneeded(void) {  static int ascresetneeded(void) {
139    static int result = 0;    static int result = 0;
140    
141  #if !defined(NO_SIGINT_TRAP) || !defined(NO_SIGSEGV_TRAP)  #if !defined(NO_SIGINT_TRAP) || !defined(NO_SIGSEGV_TRAP)
142    SigHandler lasttrap;    SigHandlerFn *lasttrap;
143    volatile SigHandler savedtrap;    volatile SigHandlerFn *savedtrap;
144    static int c=0;    static int c=0;
145  #endif  #endif
146    
# Line 199  static int ascresetneeded(void) { Line 200  static int ascresetneeded(void) {
200    return result;    return result;
201  }  }
202    
203  static  static void initstack (SigHandlerFn **traps, int *stackptr, int sig){
204  void initstack (SigHandler *traps, int *stackptr, int sig)    SigHandlerFn *old;
 {  
   SigHandler old;  
205    old = signal(sig,SIG_DFL);    old = signal(sig,SIG_DFL);
206    if (old != SIG_ERR && old != SIG_DFL) {    if (old != SIG_ERR && old != SIG_DFL) {
207      traps[0] = old;      traps[0] = old;
# Line 210  void initstack (SigHandler *traps, int * Line 209  void initstack (SigHandler *traps, int *
209      (void)signal(sig,old);      (void)signal(sig,old);
210    }    }
211  }  }
212  /*  
213   * Returns 0 if successful, 1 if out of memory, 2 otherwise.  /**
214   * Does not establish any traps, just the structures for      Initialise ASCEND signal handling
215   * maintaining them. Pushes the existing traps, if any, on  
216   * the bottom of the created stacks.      Does not establish any traps, just the structures for maintaining them.
217   * Cannot be called twice successfully.      Pushes the existing traps, if any, on the bottom of the created stacks.
218   */  
219        @NOTE Cannot be called twice successfully.
220    
221        @return 0 if successful, 1 if out of memory, 2 otherwise.
222    */
223  int Asc_SignalInit(void)  int Asc_SignalInit(void)
224  {  {
225    if (f_reset_needed != -2) {    if (f_reset_needed != -2) {
# Line 225  int Asc_SignalInit(void) Line 228  int Asc_SignalInit(void)
228    
229    /* initialize SIGFPE stack */    /* initialize SIGFPE stack */
230    if (f_fpe_traps == NULL) {    if (f_fpe_traps == NULL) {
231      f_fpe_traps = ASC_NEW_ARRAY_CLEAR(SigHandler,MAX_TRAP_DEPTH);      f_fpe_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);
232      if (f_fpe_traps == NULL) {      if (f_fpe_traps == NULL) {
233        return 1;        return 1;
234      }      }
# Line 234  int Asc_SignalInit(void) Line 237  int Asc_SignalInit(void)
237    
238    /* initialize SIGINT stack */    /* initialize SIGINT stack */
239    if (f_int_traps == NULL) {    if (f_int_traps == NULL) {
240      f_int_traps = ASC_NEW_ARRAY_CLEAR(SigHandler,MAX_TRAP_DEPTH);      f_int_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);
241      if (f_int_traps == NULL) {      if (f_int_traps == NULL) {
242        ascfree(f_fpe_traps);        ascfree(f_fpe_traps);
243        f_fpe_traps = NULL;        f_fpe_traps = NULL;
# Line 245  int Asc_SignalInit(void) Line 248  int Asc_SignalInit(void)
248    
249    /* initialize SIGSEGV stack */    /* initialize SIGSEGV stack */
250    if (f_seg_traps == NULL) {    if (f_seg_traps == NULL) {
251      f_seg_traps = ASC_NEW_ARRAY_CLEAR(SigHandler,MAX_TRAP_DEPTH);      f_seg_traps = ASC_NEW_ARRAY_CLEAR(SigHandlerFn*,MAX_TRAP_DEPTH);
252      if (f_seg_traps == NULL) {      if (f_seg_traps == NULL) {
253        ascfree(f_fpe_traps);        ascfree(f_fpe_traps);
254        f_fpe_traps = NULL;        f_fpe_traps = NULL;
# Line 277  int Asc_SignalInit(void) Line 280  int Asc_SignalInit(void)
280    return 0;    return 0;
281  }  }
282    
283  /*  /**
284   * clears and destroys the stacks of signal handlers.      Clears and destroys the stacks of signal handlers.
285   */  */
286  void Asc_SignalDestroy(void)  void Asc_SignalDestroy(void)
287  {  {
288    ascfree(f_fpe_traps);    ascfree(f_fpe_traps);
# Line 289  void Asc_SignalDestroy(void) Line 292  void Asc_SignalDestroy(void)
292    f_fpe_top_of_stack = f_int_top_of_stack = f_seg_top_of_stack =  -1;    f_fpe_top_of_stack = f_int_top_of_stack = f_seg_top_of_stack =  -1;
293  }  }
294    
295  static void reset_trap(int signum, SigHandler *tlist, int tos)  static void reset_trap(int signum, SigHandlerFn **tlist, int tos)
296  {  {
297    SigHandler tp;    SigHandlerFn *tp;
298    if ((tlist != NULL) && (tos >= 0) && (tos < MAX_TRAP_DEPTH)) {    if ((tlist != NULL) && (tos >= 0) && (tos < MAX_TRAP_DEPTH)) {
299      tp = tlist[tos];      tp = tlist[tos];
300      if (tp != SIG_ERR) {      if (tp != SIG_ERR) {
# Line 301  static void reset_trap(int signum, SigHa Line 304  static void reset_trap(int signum, SigHa
304      (void)signal(signum,SIG_DFL);      (void)signal(signum,SIG_DFL);
305    }    }
306  }  }
307  /* This function reinstalls all the signal handlers this module  /*
308   * has been informed of. This should be called after every      This function reinstalls all the signal handlers this module
309   * trapped exception and at any other time when the status of      has been informed of. This should be called after every
310   * exception handlers may have become not well defined.      trapped exception and at any other time when the status of
311   * The most recently pushed handler is installed for each supported      exception handlers may have become not well defined.
312   * signal. If nothing on stack, SIG_DFL gets installed.      The most recently pushed handler is installed for each supported
313   *_Note that if somebody installs a handler without going through      signal. If nothing on stack, SIG_DFL gets installed.
314   * our push/pop, theirs is liable to be forgotten.  
315   */      @NOTE that if somebody installs a handler without going through
316        our push/pop, theirs is liable to be forgotten.
317    */
318  void Asc_SignalRecover(int force)  void Asc_SignalRecover(int force)
319  {  {
320    if (force || f_reset_needed > 0) {    if (force || f_reset_needed > 0) {
# Line 321  void Asc_SignalRecover(int force) Line 326  void Asc_SignalRecover(int force)
326    }    }
327  }  }
328    
329  /*  /**
330   * append a pointer to the list given, if the list is not full.      Append a pointer to the list given, if the list is not full.
331   */  */
332  static int push_trap(SigHandler *tlist, int *stackptr, SigHandler tp)  static int push_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp)
333  {  {
334    if (tlist == NULL) {    if (tlist == NULL) {
335      CONSOLE_DEBUG("TLIST IS NULL");      CONSOLE_DEBUG("TLIST IS NULL");
# Line 348  static int push_trap(SigHandler *tlist, Line 353  static int push_trap(SigHandler *tlist,
353  }  }
354    
355  /*  /*
356   * Adds a handler to the stack of signal handlers for the given signal.      Add a handler to the stack of signal handlers for the given signal.
357   * There is a maximum stack limit, so returns 1 if limit exceeded.  
358   * Returns -1 if stack of signal requested does not exist.      There is a maximum stack limit, so returns 1 if limit exceeded.
359   * Pushing a NULL handler does NOT change anything at all.      Returns -1 if stack of signal requested does not exist.
360   * On a successful return, the handler has been installed and will      Pushing a NULL handler does NOT change anything at all.
361   * remain installed until a Asc_SignalHandlerPop or another push.      On a successful return, the handler has been installed and will
362   */      remain installed until a Asc_SignalHandlerPop or another push.
363  int Asc_SignalHandlerPush(int signum, SigHandler tp)  */
364    int Asc_SignalHandlerPush(int signum, SigHandlerFn *tp)
365  {  {
366    int err;    int err;
367    if (tp == NULL) {    if (tp == NULL) {
# Line 386  int Asc_SignalHandlerPush(int signum, Si Line 392  int Asc_SignalHandlerPush(int signum, Si
392  }  }
393    
394  /*  /*
395   * Returns: 0 -ok, 2 NULL list input, 1 empty list input,      Returns: 0 -ok, 2 NULL list input, 1 empty list input,
396   * -1 mismatched input tp and stack data.      -1 mismatched input tp and stack data.
397   */  */
398  static int pop_trap(SigHandler *tlist, int *stackptr, SigHandler tp)  static int pop_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp){
399  {    SigHandlerFn *oldtrap;
   SigHandler oldtrap;  
400    
401    if ((tlist == NULL) || (stackptr == NULL)) {    if ((tlist == NULL) || (stackptr == NULL)) {
402      return 2;      return 2;
# Line 405  static int pop_trap(SigHandler *tlist, i Line 410  static int pop_trap(SigHandler *tlist, i
410    return (-(oldtrap != tp));    return (-(oldtrap != tp));
411  }  }
412    
413  int Asc_SignalHandlerPop(int signum, SigHandler tp)  int Asc_SignalHandlerPop(int signum, SigHandlerFn *tp){
 {  
414    int err;    int err;
415    switch (signum) {    switch (signum) {
416    case SIGFPE:    case SIGFPE:

Legend:
Removed from v.952  
changed lines
  Added in v.953

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22