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

version 1.5, 2000/07/20 13:29:43 version 1.26, 2003/03/08 19:52:05
Line 1 Line 1
 /* signal handling  /* signal handling
   
   Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.    Copyright (C) 1995,1996,1997,1998,2000 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 <setjmp.h>  #include <setjmp.h>
 #include <string.h>  #include <string.h>
Line 31 Line 31
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #endif  #endif
 /* #include <asm/signal.h> */  /* #include <asm/signal.h> */
   #include <sys/types.h>
 #include <signal.h>  #include <signal.h>
 #include "config.h"  
 #include "forth.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 47 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  #ifdef SA_SIGINFO
 void install_signal_handler(int sig, void (*handler)(int, siginfo_t *, void *))  void install_signal_handler(int sig, void (*handler)(int, siginfo_t *, void *))
      /* installs three-argument signal handler for sig */       /* installs three-argument signal handler for sig */
Line 55  void install_signal_handler(int sig, voi Line 67  void install_signal_handler(int sig, voi
   
   action.sa_sigaction=handler;    action.sa_sigaction=handler;
   sigemptyset(&action.sa_mask);    sigemptyset(&action.sa_mask);
   action.sa_flags=SA_RESTART|SA_SIGINFO; /* pass siginfo */    action.sa_flags=SA_RESTART|SA_NODEFER|SA_SIGINFO|SA_ONSTACK; /* pass siginfo */
   sigaction(sig, &action, NULL);    sigaction(sig, &action, NULL);
 }  }
 #endif  #endif
   
 typedef void Sigfunc(int);  
   
 Sigfunc *bsd_signal(int signo, Sigfunc *func)  Sigfunc *bsd_signal(int signo, Sigfunc *func)
 {  {
   struct sigaction act, oact;    struct sigaction act, oact;
   
   act.sa_handler=func;    act.sa_handler=func;
   sigemptyset(&act.sa_mask);    sigemptyset(&act.sa_mask);
   act.sa_flags=SA_NODEFER;    act.sa_flags=SA_NODEFER; /* SA_ONSTACK does not work for graceful_exit */
   if (sigaction(signo,&act,&oact) < 0)    if (sigaction(signo,&act,&oact) < 0)
     return SIG_ERR;      return SIG_ERR;
   else    else
Line 97  signal_throw(int sig) Line 107  signal_throw(int sig)
   case SIGBUS: code=-23; break;    case SIGBUS: code=-23; break;
 #endif  #endif
   case SIGSEGV: code=-9; break;    case SIGSEGV: code=-9; break;
   #ifdef SIGPIPE
     case SIGPIPE: code=-2049; break;
   #endif
   default: code=-256-sig; break;    default: code=-256-sig; break;
   }    }
   #ifdef __CYGWIN__
     /* the SA_NODEFER apparently does not work on Cygwin 1.3.18(0.69/3/2) */
     {
       sigset_t emptyset;
       sigemptyset(&emptyset);
       sigprocmask(SIG_SETMASK, &emptyset, NULL);
     }
   #endif
   longjmp(throw_jmp_buf,code); /* !! or use siglongjmp ? */    longjmp(throw_jmp_buf,code); /* !! or use siglongjmp ? */
 }  }
   
 #ifdef SA_SIGINFO  #ifdef SA_SIGINFO
   static void
   sigaction_throw(int sig, siginfo_t *info, void *_)
   {
     signal_throw(sig);
   }
   
 static void fpe_handler(int sig, siginfo_t *info, void *_)  static void fpe_handler(int sig, siginfo_t *info, void *_)
      /* handler for SIGFPE */       /* handler for SIGFPE */
 {  {
   int code;    int code;
   
   switch(info->si_code) {    switch(info->si_code) {
   #ifdef FPE_INTDIV
   case FPE_INTDIV: code=-10; break; /* integer divide by zero */    case FPE_INTDIV: code=-10; break; /* integer divide by zero */
   #endif
   #ifdef FPE_INTOVF
   case FPE_INTOVF: code=-11; break; /* integer overflow */    case FPE_INTOVF: code=-11; break; /* integer overflow */
   #endif
   case FPE_FLTDIV: code=-42; break; /* floating point divide by zero */    case FPE_FLTDIV: code=-42; break; /* floating point divide by zero */
   case FPE_FLTOVF: code=-43; break; /* floating point overflow  */    case FPE_FLTOVF: code=-43; break; /* floating point overflow  */
   case FPE_FLTUND: code=-54; break; /* floating point underflow  */    case FPE_FLTUND: code=-54; break; /* floating point underflow  */
   case FPE_FLTRES: code=-41; break; /* floating point inexact result  */    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_FLTINV: /* invalid floating point operation  */
   case FPE_FLTSUB: /* subscript out of range  */    case FPE_FLTSUB: /* subscript out of range  */
   #endif
   default: code=-55; break;    default: code=-55; break;
   }    }
   longjmp(throw_jmp_buf,code);    longjmp(throw_jmp_buf,code);
Line 158  static void segv_handler(int sig, siginf Line 191  static void segv_handler(int sig, siginf
 #endif /* defined(SA_SIGINFO) */  #endif /* defined(SA_SIGINFO) */
   
 #ifdef SIGCONT  #ifdef SIGCONT
 static void termprep (int sig)  static void termprep(int sig)
 {  {
   bsd_signal(sig,termprep);    bsd_signal(sig,termprep);
   terminal_prepped=0;    terminal_prepped=0;
Line 169  void get_winsize() Line 202  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 178  void get_winsize() Line 212  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
Line 350  void install_signal_handlers(void) Line 384  void install_signal_handlers(void)
   };    };
   int i;    int i;
   void (*throw_handler)() = die_on_signal ? graceful_exit : signal_throw;    void (*throw_handler)() = die_on_signal ? graceful_exit : signal_throw;
   #ifdef SIGSTKSZ 
     stack_t sigstack;
     int sas_retval=-1;
   
     sigstack.ss_size=SIGSTKSZ;
     /* Actually the stack should only be ss_size large, and according to
        SUSv2 ss_sp should point to the start of the stack, but
        unfortunately Irix 6.5 (at least) expects ss_sp to point to the
        end, so we work around this issue by accomodating everyone. */
     if ((sigstack.ss_sp = my_alloc(sigstack.ss_size*2)) != NULL) {
       sigstack.ss_sp += sigstack.ss_size;
       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 361  void install_signal_handlers(void) Line 412  void install_signal_handlers(void)
   for (i = 0; i < DIM (sigs_to_quit); i++)    for (i = 0; i < DIM (sigs_to_quit); i++)
     bsd_signal(sigs_to_quit [i], graceful_exit);      bsd_signal(sigs_to_quit [i], graceful_exit);
 #ifdef SA_SIGINFO  #ifdef SA_SIGINFO
   install_signal_handler(SIGFPE, fpe_handler);    if (!die_on_signal) {
   install_signal_handler(SIGSEGV, segv_handler);  #ifdef SIGFPE
       install_signal_handler(SIGFPE, fpe_handler);
   #endif
   #ifdef SIGSEGV
       install_signal_handler(SIGSEGV, segv_handler);
 #endif  #endif
       /* use SA_ONSTACK for all signals that could come from executing
          wrong code */
   #ifdef SIGILL
       install_signal_handler(SIGILL, sigaction_throw);
   #endif
   #ifdef SIGBUS
       install_signal_handler(SIGBUS, sigaction_throw);
   #endif
   #ifdef SIGTRAP
       install_signal_handler(SIGTRAP, sigaction_throw);
   #endif
     }
   #endif /* defined(SA_SIGINFO) */
 #ifdef SIGCONT  #ifdef SIGCONT
     bsd_signal(SIGCONT, termprep);      bsd_signal(SIGCONT, termprep);
 #endif  #endif

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


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