172 |
} |
} |
173 |
f_seg_top_of_stack = -1; |
f_seg_top_of_stack = -1; |
174 |
|
|
175 |
/* push the old ones if any, on the stack. */ |
/* old signals are *not* stored */ |
176 |
initstack(f_fpe_traps, &f_fpe_top_of_stack, SIGFPE); |
initstack(f_fpe_traps, &f_fpe_top_of_stack, SIGFPE); |
177 |
initstack(f_int_traps, &f_int_top_of_stack, SIGINT); |
initstack(f_int_traps, &f_int_top_of_stack, SIGINT); |
178 |
initstack(f_seg_traps, &f_seg_top_of_stack, SIGSEGV); |
initstack(f_seg_traps, &f_seg_top_of_stack, SIGSEGV); |
272 |
case SIGINT: |
case SIGINT: |
273 |
CONSOLE_DEBUG("PUSH SIGINT"); |
CONSOLE_DEBUG("PUSH SIGINT"); |
274 |
err = push_trap(f_int_traps, &f_int_top_of_stack, tp); |
err = push_trap(f_int_traps, &f_int_top_of_stack, tp); |
|
print_stack(SIGINT,f_int_traps,f_int_top_of_stack); |
|
275 |
break; |
break; |
276 |
case SIGSEGV: |
case SIGSEGV: |
277 |
/* CONSOLE_DEBUG("PUSH SIGSEGV"); */ |
/* CONSOLE_DEBUG("PUSH SIGSEGV"); */ |
280 |
default: |
default: |
281 |
return -1; |
return -1; |
282 |
} |
} |
283 |
if (err != 0) { |
if(err != 0){ |
284 |
ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Error from push_trap or fenv_push (err = %d, signal=#%d).",err, signum); |
ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Error from push_trap or fenv_push (err = %d, signal=#%d).",err, signum); |
285 |
return err; |
return err; |
286 |
} |
} |
301 |
|
|
302 |
switch (signum) { |
switch (signum) { |
303 |
case SIGFPE: |
case SIGFPE: |
304 |
//CONSOLE_DEBUG("POP SIGFPE"); |
CONSOLE_DEBUG("POP SIGFPE"); |
305 |
err = pop_trap(f_fpe_traps, &f_fpe_top_of_stack, tp); |
err = pop_trap(f_fpe_traps, &f_fpe_top_of_stack, tp); |
306 |
#ifdef HAVE_C99FPE |
#if 0 && defined(HAVE_C99FPE) |
307 |
err = fenv_pop(f_fenv_stack, &f_fenv_stack_top); |
if(!err){ |
308 |
|
err = fenv_pop(f_fenv_stack, &f_fenv_stack_top); |
309 |
|
} |
310 |
#endif |
#endif |
311 |
break; |
break; |
312 |
case SIGINT: |
case SIGINT: |
313 |
CONSOLE_DEBUG("POP SIGINT"); |
CONSOLE_DEBUG("POP SIGINT"); |
314 |
err = pop_trap(f_int_traps, &f_int_top_of_stack, tp); |
err = pop_trap(f_int_traps, &f_int_top_of_stack, tp); |
|
print_stack(SIGINT,f_int_traps,f_int_top_of_stack); |
|
315 |
break; |
break; |
316 |
case SIGSEGV: |
case SIGSEGV: |
317 |
/* CONSOLE_DEBUG("POP SIGSEGV"); */ |
CONSOLE_DEBUG("POP SIGSEGV"); |
318 |
err = pop_trap(f_seg_traps, &f_seg_top_of_stack, tp); |
err = pop_trap(f_seg_traps, &f_seg_top_of_stack, tp); |
319 |
break; |
break; |
320 |
default: |
default: |
326 |
ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Asc_Signal (%d) stack pop mismatch.",signum); |
ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Asc_Signal (%d) stack pop mismatch.",signum); |
327 |
return err; |
return err; |
328 |
} |
} |
329 |
Asc_SignalRecover(TRUE); |
SIGNAL(signum,Asc_SignalStackTop(signum)); |
330 |
return 0; |
return 0; |
331 |
} |
} |
332 |
|
|
378 |
int Asc_SignalStackLength(int signum){ |
int Asc_SignalStackLength(int signum){ |
379 |
switch(signum){ |
switch(signum){ |
380 |
case SIGINT: |
case SIGINT: |
381 |
return f_int_top_of_stack; |
return f_int_top_of_stack + 1; |
382 |
case SIGFPE: |
case SIGFPE: |
383 |
return f_fpe_top_of_stack; |
return f_fpe_top_of_stack + 1; |
384 |
case SIGSEGV: |
case SIGSEGV: |
385 |
return f_seg_top_of_stack; |
return f_seg_top_of_stack + 1; |
386 |
default: |
default: |
387 |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Invalid signal %d",signum); |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"Invalid signal %d",signum); |
388 |
|
return 0; |
389 |
} |
} |
390 |
} |
} |
391 |
|
|
392 |
|
SigHandlerFn *Asc_SignalStackTop(int signum){ |
393 |
|
SigHandlerFn **stack; |
394 |
|
int *ptr; |
395 |
|
switch(signum){ |
396 |
|
case SIGINT: |
397 |
|
stack = f_int_traps; ptr = &f_int_top_of_stack; break; |
398 |
|
case SIGFPE: |
399 |
|
stack = f_fpe_traps; ptr = &f_fpe_top_of_stack; break; |
400 |
|
case SIGSEGV: |
401 |
|
stack = f_seg_traps; ptr = &f_seg_top_of_stack; break; |
402 |
|
} |
403 |
|
if(stack==NULL)return NULL; |
404 |
|
if(ptr==NULL)return NULL; |
405 |
|
if(*ptr < 0) return NULL; |
406 |
|
if(*ptr >= MAX_TRAP_DEPTH) return NULL; |
407 |
|
return stack[*ptr]; |
408 |
|
} |
409 |
|
|
410 |
/*------------------------------------------------------------------------------ |
/*------------------------------------------------------------------------------ |
411 |
UTILITY FUNCTIONS |
UTILITY FUNCTIONS |
443 |
traps[0] = old; |
traps[0] = old; |
444 |
*stackptr = 0; |
*stackptr = 0; |
445 |
(void)SIGNAL(sig,old); |
(void)SIGNAL(sig,old); |
446 |
|
}else{ |
447 |
|
CONSOLE_DEBUG("Initialising stack for signal %d as empty",sig); |
448 |
|
*stackptr = -1; |
449 |
} |
} |
450 |
} |
} |
451 |
|
|
453 |
SigHandlerFn *tp; |
SigHandlerFn *tp; |
454 |
SigHandlerFn *oldfn; |
SigHandlerFn *oldfn; |
455 |
if ((tlist != NULL) && (tos >= 0) && (tos < MAX_TRAP_DEPTH)) { |
if ((tlist != NULL) && (tos >= 0) && (tos < MAX_TRAP_DEPTH)) { |
456 |
oldfn = SIGNAL(signum,SIG_DFL); |
oldfn = signal(signum,SIG_DFL); |
457 |
tp = tlist[tos]; |
tp = tlist[tos]; |
458 |
if (tp != SIG_ERR) { |
if (tp != SIG_ERR) { |
459 |
#ifdef ASC_RESETNEEDED |
#ifndef ASC_RESETNEEDED |
|
# ifdef SIGNAL_DEBUG |
|
|
CONSOLE_DEBUG("Resetting signal #%d (was %p, new %p)",signum,oldfn,tp); |
|
|
# endif |
|
|
(void)SIGNAL(signum,tp); |
|
|
#else |
|
|
# ifdef SIGNAL_DEBUG |
|
460 |
if(tp!=oldfn){ |
if(tp!=oldfn){ |
461 |
ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Resetting signal %d (shouldn't be necessary)",signum); |
ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Resetting signal %d (was=%p, new=%p",signum,oldfn,tp); |
|
(void)SIGNAL(signum,tp); |
|
462 |
} |
} |
|
# endif |
|
463 |
#endif |
#endif |
464 |
|
(void)signal(signum,tp); |
465 |
} |
} |
466 |
}else{ |
}else{ |
467 |
(void)SIGNAL(signum,SIG_DFL); |
(void)SIGNAL(signum,SIG_DFL); |
473 |
*/ |
*/ |
474 |
static int push_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp){ |
static int push_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp){ |
475 |
if (tlist == NULL) { |
if (tlist == NULL) { |
476 |
CONSOLE_DEBUG("TLIST IS NULL"); |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"TLIST is NULL"); |
477 |
return -1; |
return -1; |
478 |
} |
} |
479 |
if (stackptr == NULL) { |
if (stackptr == NULL) { |
480 |
CONSOLE_DEBUG("STACKPTR IS NULL"); |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"STACKPTR is NULL"); |
481 |
return -1; |
return -1; |
482 |
} |
} |
483 |
if (tp == NULL) { |
if (tp == NULL) { |
484 |
CONSOLE_DEBUG("TP IS NULL"); |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"TP is NULL"); |
485 |
return 2; |
return 2; |
486 |
} |
} |
487 |
if (*stackptr > MAX_TRAP_DEPTH-1) { |
if (*stackptr > MAX_TRAP_DEPTH-1) { |
488 |
CONSOLE_DEBUG("TLIST LENGTH = CAPACITY"); |
ERROR_REPORTER_HERE(ASC_PROG_ERR,"stackptr >= capacity"); |
489 |
return 1; |
return 1; |
490 |
} |
} |
491 |
++(*stackptr); |
++(*stackptr); |
494 |
} |
} |
495 |
|
|
496 |
|
|
497 |
/* |
/** |
498 |
Returns: 0 -ok, 2 NULL list input, 1 empty list input, |
@return 0 on success, 2 on NULL tlist or stackptr input, 1 on empty stack |
499 |
-1 mismatched input tp and stack data. |
or -1 on mismatched input tp and stack data |
500 |
|
|
501 |
|
Any non-zero return code leaves the stack as it was. |
502 |
*/ |
*/ |
503 |
static int pop_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp){ |
static int pop_trap(SigHandlerFn **tlist, int *stackptr, SigHandlerFn *tp){ |
504 |
SigHandlerFn *oldtrap; |
SigHandlerFn *oldtrap; |
510 |
return 1; |
return 1; |
511 |
} |
} |
512 |
oldtrap = tlist[*stackptr]; |
oldtrap = tlist[*stackptr]; |
513 |
|
if(oldtrap != tp)return -1; |
514 |
tlist[*stackptr] = NULL; |
tlist[*stackptr] = NULL; |
515 |
--(*stackptr); |
--(*stackptr); |
516 |
return (-(oldtrap != tp)); |
return 0; |
517 |
} |
} |
518 |
|
|
519 |
static void print_stack(int signum, SigHandlerFn **tlist, int tos){ |
static void print_stack(int signum, SigHandlerFn **tlist, int tos){ |
520 |
int i; |
int i; |
521 |
CONSOLE_DEBUG("---------------"); |
CONSOLE_DEBUG("---------------"); |
522 |
for(i=0;i<tos;++i){ |
for(i=0;i<=tos;++i){ |
523 |
CONSOLE_DEBUG("Signal #%d, stack %d/%d: %p",signum,i,tos,tlist[i]); |
CONSOLE_DEBUG("Signal #%d, stack %d/%d: %p",signum,i,tos,tlist[i]); |
524 |
} |
} |
525 |
CONSOLE_DEBUG("--------------- = %d",tos); |
CONSOLE_DEBUG("--------------- = %d",tos); |