Diff for /gforth/engine/signals.c between versions 1.23 and 1.49

version 1.23, 2003/02/01 14:28:07 version 1.49, 2012/03/24 01:17:52
Line 1 Line 1
 /* signal handling  /* signal handling
   
   Copyright (C) 1995,1996,1997,1998,2000 Free Software Foundation, Inc.    Copyright (C) 1995,1996,1997,1998,2000,2003,2006,2007,2011 Free Software Foundation, Inc.
   
   This file is part of Gforth.    This file is part of Gforth.
   
   Gforth is free software; you can redistribute it and/or    Gforth is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License    modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2    as published by the Free Software Foundation, either version 3
   of the License, or (at your option) any later version.    of the License, or (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,    This program is distributed in the hope that it will be useful,
Line 15 Line 15
   GNU General Public License for more details.    GNU General Public License for more details.
   
   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, see http://www.gnu.org/licenses/.
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.  
   
 */  */
   
Line 30 Line 29
 #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 <sys/types.h>  #include <sys/types.h>
 #include <signal.h>  #include <signal.h>
   #include <termios.h>
 #include "io.h"  #include "io.h"
   
   #ifdef HAS_DEBUG
   extern int debug;
   # define debugp(x...) do { if (debug) fprintf(x); } while (0)
   #else
   # define perror(x...)
   # define fprintf(x...)
   # define debugp(x...)
   #endif
   
 #ifndef HAVE_STACK_T  #ifndef HAVE_STACK_T
 /* Darwin uses "struct sigaltstack" instead of "stack_t" */  /* Darwin uses "struct sigaltstack" instead of "stack_t" */
 typedef struct sigaltstack stack_t;  typedef struct sigaltstack stack_t;
 #endif  #endif
   
 #define DEFAULTCOLS 80  #define DEFAULTCOLS 80
 #if defined(MSDOS) || defined (_WIN32)  #if defined(MSDOS) || defined (_WIN32) || defined (__CYGWIN__)
 #define DEFAULTROWS 25  #define DEFAULTROWS 25
 #else  #else
 #define DEFAULTROWS 24  #define DEFAULTROWS 24
Line 72  void install_signal_handler(int sig, voi Line 80  void install_signal_handler(int sig, voi
 }  }
 #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;
Line 95  graceful_exit (int sig) Line 101  graceful_exit (int sig)
   exit (0x80|sig);    exit (0x80|sig);
 }  }
   
 jmp_buf throw_jmp_buf;  __thread jmp_buf * throw_jmp_handler;
   
   void throw(int code)
   {
     debugp(stderr,"\nthrow code %d to %p\n", code, *throw_jmp_handler);
     longjmp(*throw_jmp_handler,code); /* !! or use siglongjmp ? */
   }
   
 static void   static void 
 signal_throw(int sig)  signal_throw(int sig)
 {  {
   int code;    int code;
     debugp(stderr,"\ncaught signal %d\n", sig);
   
   switch (sig) {    switch (sig) {
   case SIGINT: code=-28; break;    case SIGINT: code=-28; break;
Line 109  signal_throw(int sig) Line 122  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;
   }    }
   longjmp(throw_jmp_buf,code); /* !! or use siglongjmp ? */  #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
     throw(code);
 }  }
   
 #ifdef SA_SIGINFO  #ifdef SA_SIGINFO
   static void
   sigaction_throw(int sig, siginfo_t *info, void *_)
   {
     debugp(stderr,"\nsigaction_throw %d %p %p\n", sig, info, _);
     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;
   
     debugp(stderr,"\nfpe_handler %d %x %x\n", sig, info, _);
   
   switch(info->si_code) {    switch(info->si_code) {
 #ifdef FPE_INTDIV  #ifdef FPE_INTDIV
   case FPE_INTDIV: code=-10; break; /* integer divide by zero */    case FPE_INTDIV: code=BALL_DIVZERO; break;
 #endif  #endif
 #ifdef FPE_INTOVF  #ifdef FPE_INTOVF
   case FPE_INTOVF: code=-11; break; /* integer overflow */    case FPE_INTOVF: code=BALL_RESULTRANGE; break; /* integer overflow */
 #endif  #endif
   #ifdef FPE_FLTDIV
   case FPE_FLTDIV: code=-42; break; /* floating point divide by zero */    case FPE_FLTDIV: code=-42; break; /* floating point divide by zero */
   #endif
   #ifdef FPE_FLTOVF
   case FPE_FLTOVF: code=-43; break; /* floating point overflow  */    case FPE_FLTOVF: code=-43; break; /* floating point overflow  */
   #endif
   #ifdef FPE_FLTUND
   case FPE_FLTUND: code=-54; break; /* floating point underflow  */    case FPE_FLTUND: code=-54; break; /* floating point underflow  */
   #endif
   #ifdef FPE_FLTRES
   case FPE_FLTRES: code=-41; break; /* floating point inexact result  */    case FPE_FLTRES: code=-41; break; /* floating point inexact result  */
   #endif
 #if 0 /* defined by Unix95, but unnecessary */  #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  #endif
   default: code=-55; break;    default: code=-55; break;
   }    }
   longjmp(throw_jmp_buf,code);    throw(code);
 }  }
   
   
Line 158  static void segv_handler(int sig, siginf Line 199  static void segv_handler(int sig, siginf
   Address addr=info->si_addr;    Address addr=info->si_addr;
   ImageHeader *h=gforth_header;    ImageHeader *h=gforth_header;
   
     debugp(stderr,"\nsegv_handler %d %p %p\n", sig, info, _);
   
   if (JUSTUNDER(addr, h->data_stack_base))    if (JUSTUNDER(addr, h->data_stack_base))
     code=-3;      code=-3;
   else if (JUSTOVER(addr, NEXTPAGE(h->data_stack_base+h->data_stack_size)))    else if (JUSTOVER(addr, NEXTPAGE(h->data_stack_base+h->data_stack_size)))
Line 170  static void segv_handler(int sig, siginf Line 213  static void segv_handler(int sig, siginf
     code=-44;      code=-44;
   else if (JUSTOVER(addr, NEXTPAGE(h->fp_stack_base+h->fp_stack_size)))    else if (JUSTOVER(addr, NEXTPAGE(h->fp_stack_base+h->fp_stack_size)))
     code=-45;      code=-45;
   longjmp(throw_jmp_buf,code);    throw(code);
 }  }
   
 #endif /* defined(SA_SIGINFO) */  #endif /* defined(SA_SIGINFO) */
Line 204  void get_winsize() Line 247  void get_winsize()
 #endif  #endif
   if (rows==0)    if (rows==0)
     rows=DEFAULTROWS;      rows=DEFAULTROWS;
   if (rows==0)    if (cols==0)
     cols=DEFAULTCOLS;      cols=DEFAULTCOLS;
 }  }
   
Line 291  void install_signal_handlers(void) Line 334  void install_signal_handlers(void)
   };    };
 #endif  #endif
   
     static short async_sigs_to_throw [] = {
   #ifdef SIGINT
       SIGINT,
   #endif
   #ifdef SIGALRM
       SIGALRM,
   #endif
   #ifdef SIGPOLL
       SIGPOLL,
   #endif
   #ifdef SIGPROF
       SIGPROF,
   #endif
   #ifdef SIGURG
       SIGURG,
   #endif
   #ifdef SIGPIPE
       SIGPIPE,
   #endif
   #ifdef SIGUSR1
       SIGUSR1,
   #endif
   #ifdef SIGUSR2
       SIGUSR2,
   #endif
   #ifdef SIGVTALRM
       SIGVTALRM,
   #endif
   #ifdef SIGXFSZ
       SIGXFSZ,
   #endif
     };
   
   static short sigs_to_throw [] = {    static short sigs_to_throw [] = {
 #ifdef SIGBREAK  #ifdef SIGBREAK
     SIGBREAK,      SIGBREAK,
 #endif  #endif
 #ifdef SIGINT  
     SIGINT,  
 #endif  
 #ifdef SIGILL  #ifdef SIGILL
     SIGILL,      SIGILL,
 #endif  #endif
Line 313  void install_signal_handlers(void) Line 386  void install_signal_handlers(void)
 #ifdef SIGSEGV  #ifdef SIGSEGV
     SIGSEGV,      SIGSEGV,
 #endif  #endif
 #ifdef SIGALRM  
     SIGALRM,  
 #endif  
 #ifdef SIGPIPE  
     SIGPIPE,  
 #endif  
 #ifdef SIGPOLL  
     SIGPOLL,  
 #endif  
 #ifdef SIGPROF  
     SIGPROF,  
 #endif  
 #ifdef SIGBUS  #ifdef SIGBUS
     SIGBUS,      SIGBUS,
 #endif  #endif
Line 334  void install_signal_handlers(void) Line 395  void install_signal_handlers(void)
 #ifdef SIGTRAP  #ifdef SIGTRAP
     SIGTRAP,      SIGTRAP,
 #endif  #endif
 #ifdef SIGURG  
     SIGURG,  
 #endif  
 #ifdef SIGUSR1  
     SIGUSR1,  
 #endif  
 #ifdef SIGUSR2  
     SIGUSR2,  
 #endif  
 #ifdef SIGVTALRM  
     SIGVTALRM,  
 #endif  
 #ifdef SIGXFSZ  
     SIGXFSZ,  
 #endif  
   };    };
   
   static short sigs_to_quit [] = {    static short sigs_to_quit [] = {
 #ifdef SIGQUIT  #ifdef SIGQUIT
     SIGQUIT,      SIGQUIT,
Line 369  void install_signal_handlers(void) Line 416  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   #if defined(SIGSTKSZ)
   stack_t sigstack;    stack_t sigstack;
   int sas_retval=-1;    int sas_retval=-1;
   
Line 378  void install_signal_handlers(void) Line 425  void install_signal_handlers(void)
      SUSv2 ss_sp should point to the start of the stack, but       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       unfortunately Irix 6.5 (at least) expects ss_sp to point to the
      end, so we work around this issue by accomodating everyone. */       end, so we work around this issue by accomodating everyone. */
   if ((sigstack.ss_sp = my_alloc(sigstack.ss_size*2)) != NULL) {    if ((sigstack.ss_sp = gforth_alloc(sigstack.ss_size*2)) != NULL) {
     sigstack.ss_sp += sigstack.ss_size;      sigstack.ss_sp += sigstack.ss_size;
     sigstack.ss_flags=0;      sigstack.ss_flags=0;
     sas_retval=sigaltstack(&sigstack,(stack_t *)0);      sas_retval=sigaltstack(&sigstack,(stack_t *)0);
   }    }
   if (debug)  #if defined(HAS_FILE) || !defined(STANDALONE)
     fprintf(stderr,"sigaltstack: %s\n",strerror(sas_retval));    debugp(stderr,"sigaltstack: %s\n",strerror(sas_retval));
   #endif
 #endif  #endif
   
 #define DIM(X)          (sizeof (X) / sizeof *(X))  #define DIM(X)          (sizeof (X) / sizeof *(X))
Line 394  void install_signal_handlers(void) Line 442  void install_signal_handlers(void)
 */  */
   for (i = 0; i < DIM (sigs_to_throw); i++)    for (i = 0; i < DIM (sigs_to_throw); i++)
     bsd_signal(sigs_to_throw[i], throw_handler);      bsd_signal(sigs_to_throw[i], throw_handler);
     for (i = 0; i < DIM (async_sigs_to_throw); i++)
       bsd_signal(async_sigs_to_throw[i], 
                  ignore_async_signals ? SIG_IGN : throw_handler);
   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
   if (!die_on_signal) {    if (!die_on_signal) {
   #ifdef SIGFPE
     install_signal_handler(SIGFPE, fpe_handler);      install_signal_handler(SIGFPE, fpe_handler);
   #endif
   #ifdef SIGSEGV
     install_signal_handler(SIGSEGV, segv_handler);      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.23  
changed lines
  Added in v.1.49


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