Diff for /gforth/engine/signals.c between versions 1.1 and 1.5

version 1.1, 1999/02/28 08:37:45 version 1.5, 2000/07/20 13:29:43
Line 24 Line 24
 #define _GNU_SOURCE  #define _GNU_SOURCE
   
 #include <stdio.h>  #include <stdio.h>
 #include <signal.h>  
 #include <setjmp.h>  #include <setjmp.h>
 #include <string.h>  #include <string.h>
 #include <stdlib.h>  #include <stdlib.h>
 #if !defined(apollo) && !defined(MSDOS)  #if !defined(apollo) && !defined(MSDOS)
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #endif  #endif
   /* #include <asm/signal.h> */
   #include <signal.h>
 #include "config.h"  #include "config.h"
 #include "forth.h"  #include "forth.h"
 #include "io.h"  #include "io.h"
Line 46 Line 47
 UCell cols=DEFAULTCOLS;  UCell cols=DEFAULTCOLS;
 UCell rows=DEFAULTROWS;  UCell rows=DEFAULTROWS;
   
   #ifdef SA_SIGINFO
   void install_signal_handler(int sig, void (*handler)(int, siginfo_t *, void *))
        /* installs three-argument signal handler for sig */
   {
     struct sigaction action;
   
     action.sa_sigaction=handler;
     sigemptyset(&action.sa_mask);
     action.sa_flags=SA_RESTART|SA_SIGINFO; /* pass siginfo */
     sigaction(sig, &action, NULL);
   }
   #endif
   
   typedef void Sigfunc(int);
   
   Sigfunc *bsd_signal(int signo, Sigfunc *func)
   {
     struct sigaction act, oact;
   
     act.sa_handler=func;
     sigemptyset(&act.sa_mask);
     act.sa_flags=SA_NODEFER;
     if (sigaction(signo,&act,&oact) < 0)
       return SIG_ERR;
     else
       return oact.sa_handler;
   }
   
 static void  static void
 graceful_exit (int sig)  graceful_exit (int sig)
Line 61  static void Line 89  static void
 signal_throw(int sig)  signal_throw(int sig)
 {  {
   int code;    int code;
   struct {  
     int signal;    switch (sig) {
     int throwcode;    case SIGINT: code=-28; break;
   } *p, throwtable[] = {    case SIGFPE: code=-55; break;
     { SIGINT, -28 },  
     { SIGFPE, -55 },  
 #ifdef SIGBUS  #ifdef SIGBUS
     { SIGBUS, -23 },    case SIGBUS: code=-23; break;
 #endif  #endif
     { SIGSEGV, -9 },    case SIGSEGV: code=-9; break;
   };    default: code=-256-sig; break;
   signal(sig,signal_throw);    }
   for (code=-256-sig, p=throwtable; p<throwtable+(sizeof(throwtable)/sizeof(*p)); p++)    longjmp(throw_jmp_buf,code); /* !! or use siglongjmp ? */
     if (sig == p->signal) {  }
       code = p->throwcode;  
       break;  #ifdef SA_SIGINFO
     }  static void fpe_handler(int sig, siginfo_t *info, void *_)
   longjmp(throw_jmp_buf,code); /* or use siglongjmp ? */       /* handler for SIGFPE */
   {
     int code;
   
     switch(info->si_code) {
     case FPE_INTDIV: code=-10; break; /* integer divide by zero */
     case FPE_INTOVF: code=-11; break; /* integer overflow */
     case FPE_FLTDIV: code=-42; break; /* floating point divide by zero */
     case FPE_FLTOVF: code=-43; break; /* floating point overflow  */
     case FPE_FLTUND: code=-54; break; /* floating point underflow  */
     case FPE_FLTRES: code=-41; break; /* floating point inexact result  */
     case FPE_FLTINV: /* invalid floating point operation  */
     case FPE_FLTSUB: /* subscript out of range  */
     default: code=-55; break;
     }
     longjmp(throw_jmp_buf,code);
   }
   
   
   #define SPILLAGE 128
   /* if there's a SIGSEGV within SPILLAGE bytes of some stack, we assume
      that this stack has over/underflowed */
   
   #define JUSTUNDER(addr1,addr2) (((UCell)((addr2)-1-(addr1)))<SPILLAGE)
   /* true is addr1 is just under addr2 */
   
   #define JUSTOVER(addr1,addr2) (((UCell)((addr1)-(addr2)))<SPILLAGE)
   
   #define NEXTPAGE(addr) ((Address)((((UCell)(addr)-1)&-pagesize)+pagesize))
   
   static void segv_handler(int sig, siginfo_t *info, void *_)
   {
     int code=-9;
     Address addr=info->si_addr;
     ImageHeader *h=gforth_header;
   
     if (JUSTUNDER(addr, h->data_stack_base))
       code=-3;
     else if (JUSTOVER(addr, NEXTPAGE(h->data_stack_base+h->data_stack_size)))
       code=-4;
     else if (JUSTUNDER(addr, h->return_stack_base))
       code=-5;
     else if (JUSTOVER(addr, NEXTPAGE(h->return_stack_base+h->return_stack_size)))
       code=-6;
     else if (JUSTUNDER(addr, h->fp_stack_base))
       code=-44;
     else if (JUSTOVER(addr, NEXTPAGE(h->fp_stack_base+h->fp_stack_size)))
       code=-45;
     longjmp(throw_jmp_buf,code);
 }  }
   
   #endif /* defined(SA_SIGINFO) */
   
 #ifdef SIGCONT  #ifdef SIGCONT
 static void termprep (int sig)  static void termprep (int sig)
 {  {
   signal(sig,termprep);    bsd_signal(sig,termprep);
   terminal_prepped=0;    terminal_prepped=0;
 }  }
 #endif  #endif
Line 116  void get_winsize() Line 192  void get_winsize()
 #ifdef SIGWINCH  #ifdef SIGWINCH
 static void change_winsize(int sig)  static void change_winsize(int sig)
 {  {
   signal(sig,change_winsize);    /* signal(sig,change_winsize); should not be necessary with bsd_signal */
 #ifdef TIOCGWINSZ  #ifdef TIOCGWINSZ
   get_winsize();    get_winsize();
 #endif  #endif
 }  }
 #endif  #endif
   
 void install_signal_handlers (void)  void install_signal_handlers(void)
 {  {
   
 #if 0  #if 0
Line 256  void install_signal_handlers (void) Line 332  void install_signal_handlers (void)
 #endif  #endif
   };    };
   static short sigs_to_quit [] = {    static short sigs_to_quit [] = {
 #ifdef SIGHUP  
     SIGHUP,  
 #endif  
 #ifdef SIGQUIT  #ifdef SIGQUIT
     SIGQUIT,      SIGQUIT,
 #endif  #endif
   #ifdef SIGHUP
       SIGHUP,
   #endif
 #ifdef SIGABRT  #ifdef SIGABRT
     SIGABRT,      SIGABRT,
 #endif  #endif
Line 273  void install_signal_handlers (void) Line 349  void install_signal_handlers (void)
 #endif  #endif
   };    };
   int i;    int i;
     void (*throw_handler)() = die_on_signal ? graceful_exit : signal_throw;
   
 #define DIM(X)          (sizeof (X) / sizeof *(X))  #define DIM(X)          (sizeof (X) / sizeof *(X))
 /*  /*
Line 280  void install_signal_handlers (void) Line 357  void install_signal_handlers (void)
     signal (sigs_to_ignore [i], SIG_IGN);      signal (sigs_to_ignore [i], SIG_IGN);
 */  */
   for (i = 0; i < DIM (sigs_to_throw); i++)    for (i = 0; i < DIM (sigs_to_throw); i++)
     signal (sigs_to_throw [i], die_on_signal ? graceful_exit : signal_throw);      bsd_signal(sigs_to_throw[i], throw_handler);
   for (i = 0; i < DIM (sigs_to_quit); i++)    for (i = 0; i < DIM (sigs_to_quit); i++)
     signal (sigs_to_quit [i], graceful_exit);      bsd_signal(sigs_to_quit [i], graceful_exit);
   #ifdef SA_SIGINFO
     install_signal_handler(SIGFPE, fpe_handler);
     install_signal_handler(SIGSEGV, segv_handler);
   #endif
 #ifdef SIGCONT  #ifdef SIGCONT
     signal (SIGCONT, termprep);      bsd_signal(SIGCONT, termprep);
 #endif  #endif
 #ifdef SIGWINCH  #ifdef SIGWINCH
     signal (SIGWINCH, change_winsize);      bsd_signal(SIGWINCH, change_winsize);
 #endif  #endif
 }  }

Removed from v.1.1  
changed lines
  Added in v.1.5


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