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

version 1.1, 1999/02/28 08:37:45 version 1.21, 2003/01/19 23:35:34
Line 1 Line 1
 /* signal handling  /* signal handling
   
   Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.    Copyright (C) 1995-2003 Free Software Foundation, Inc.
   
   This file is part of Gforth.    This file is part of Gforth.
   
Line 16 Line 16
   
   You should have received a copy of the GNU General Public License    You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software    along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   
 */  */
   
   
 #define _GNU_SOURCE  #include "config.h"
   #include "forth.h"
 #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 "config.h"  /* #include <asm/signal.h> */
 #include "forth.h"  #include <sys/types.h>
   #include <signal.h>
 #include "io.h"  #include "io.h"
   
   #ifndef HAVE_STACK_T
   /* Darwin uses "struct sigaltstack" instead of "stack_t" */
   typedef struct sigaltstack stack_t;
   #endif
   
 #define DEFAULTCOLS 80  #define DEFAULTCOLS 80
 #if defined(MSDOS) || defined (_WIN32)  #if defined(MSDOS) || defined (_WIN32)
Line 46 Line 50
 UCell cols=DEFAULTCOLS;  UCell cols=DEFAULTCOLS;
 UCell rows=DEFAULTROWS;  UCell rows=DEFAULTROWS;
   
   #ifndef SA_NODEFER
   #define SA_NODEFER 0
   /* systems that don't have SA_NODEFER hopefully don't block anyway */
   #endif
   
   #ifndef SA_ONSTACK
   #define SA_ONSTACK 0
   #endif
   
   #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_NODEFER|SA_SIGINFO|SA_ONSTACK; /* 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; /* SA_ONSTACK does not work for graceful_exit */
     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 101  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) {
   #ifdef FPE_INTDIV
     case FPE_INTDIV: code=-10; break; /* integer divide by zero */
   #endif
   #ifdef FPE_INTOVF
     case FPE_INTOVF: code=-11; break; /* integer overflow */
   #endif
     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  */
   #if 0 /* defined by Unix95, but unnecessary */
     case FPE_FLTINV: /* invalid floating point operation  */
     case FPE_FLTSUB: /* subscript out of range  */
   #endif
     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 93  void get_winsize() Line 187  void get_winsize()
 {  {
 #ifdef TIOCGWINSZ  #ifdef TIOCGWINSZ
   struct winsize size;    struct winsize size;
     size.ws_row = size.ws_col = 0;
       
   if (ioctl (1, TIOCGWINSZ, (char *) &size) >= 0) {    if (ioctl (1, TIOCGWINSZ, (char *) &size) >= 0) {
     rows = size.ws_row;      rows = size.ws_row;
Line 102  void get_winsize() Line 197  void get_winsize()
   char *s;    char *s;
   if ((s=getenv("LINES"))) {    if ((s=getenv("LINES"))) {
     rows=atoi(s);      rows=atoi(s);
     if (rows==0)  
       rows=DEFAULTROWS;  
   }    }
   if ((s=getenv("COLUMNS"))) {    if ((s=getenv("COLUMNS"))) {
     rows=atoi(s);      rows=atoi(s);
     if (rows==0)  
       cols=DEFAULTCOLS;  
   }    }
 #endif  #endif
     if (rows==0)
       rows=DEFAULTROWS;
     if (rows==0)
       cols=DEFAULTCOLS;
 }  }
   
 #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 351  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 368  void install_signal_handlers (void)
 #endif  #endif
   };    };
   int i;    int i;
     void (*throw_handler)() = die_on_signal ? graceful_exit : signal_throw;
   #ifdef SIGSTKSZ 
     stack_t sigstack;
     int sas_retval=-1;
   
     sigstack.ss_size=SIGSTKSZ;
     if ((sigstack.ss_sp = my_alloc(sigstack.ss_size)) != NULL) {
       sigstack.ss_flags=0;
       sas_retval=sigaltstack(&sigstack,(stack_t *)0);
     }
     if (debug)
       fprintf(stderr,"sigaltstack: %s\n",strerror(sas_retval));
   #endif
   
 #define DIM(X)          (sizeof (X) / sizeof *(X))  #define DIM(X)          (sizeof (X) / sizeof *(X))
 /*  /*
Line 280  void install_signal_handlers (void) Line 388  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
     if (!die_on_signal) {
       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.21


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