File:  [gforth] / gforth / engine / signals.c
Revision 1.2: download - view: text, annotated - select for diffs
Sun Feb 28 14:50:44 1999 UTC (23 years, 5 months ago) by anton
Branches: MAIN
CVS tags: HEAD
started working on better signal handlers

    1: /* signal handling
    2: 
    3:   Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
    4: 
    5:   This file is part of Gforth.
    6: 
    7:   Gforth is free software; you can redistribute it and/or
    8:   modify it under the terms of the GNU General Public License
    9:   as published by the Free Software Foundation; either version 2
   10:   of the License, or (at your option) any later version.
   11: 
   12:   This program is distributed in the hope that it will be useful,
   13:   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15:   GNU General Public License for more details.
   16: 
   17:   You should have received a copy of the GNU General Public License
   18:   along with this program; if not, write to the Free Software
   19:   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20: 
   21: */
   22: 
   23: 
   24: #define _GNU_SOURCE
   25: 
   26: #include <stdio.h>
   27: #include <setjmp.h>
   28: #include <string.h>
   29: #include <stdlib.h>
   30: #if !defined(apollo) && !defined(MSDOS)
   31: #include <sys/ioctl.h>
   32: #endif
   33: /* #include <asm/signal.h> */
   34: #include <signal.h>
   35: #include "config.h"
   36: #include "forth.h"
   37: #include "io.h"
   38: 
   39: 
   40: #define DEFAULTCOLS 80
   41: #if defined(MSDOS) || defined (_WIN32)
   42: #define DEFAULTROWS 25
   43: #else
   44: #define DEFAULTROWS 24
   45: #endif
   46: 
   47: UCell cols=DEFAULTCOLS;
   48: UCell rows=DEFAULTROWS;
   49: 
   50: 
   51: static void
   52: graceful_exit (int sig)
   53: {
   54:   deprep_terminal();
   55:   fprintf (stderr, "\n\n%s.\n", strsignal (sig));
   56:   exit (0x80|sig);
   57: }
   58: 
   59: jmp_buf throw_jmp_buf;
   60: 
   61: static void 
   62: signal_throw(int sig)
   63: {
   64:   int code;
   65:   struct {
   66:     int signal;
   67:     int throwcode;
   68:   } *p, throwtable[] = {
   69:     { SIGINT, -28 },
   70:     { SIGFPE, -55 },
   71: #ifdef SIGBUS
   72:     { SIGBUS, -23 },
   73: #endif
   74:     { SIGSEGV, -9 },
   75:   };
   76:   signal(sig,signal_throw);
   77:   for (code=-256-sig, p=throwtable; p<throwtable+(sizeof(throwtable)/sizeof(*p)); p++)
   78:     if (sig == p->signal) {
   79:       code = p->throwcode;
   80:       break;
   81:     }
   82:   longjmp(throw_jmp_buf,code); /* or use siglongjmp ? */
   83: }
   84: 
   85: #ifdef SIGCONT
   86: static void termprep (int sig)
   87: {
   88:   signal(sig,termprep);
   89:   terminal_prepped=0;
   90: }
   91: #endif
   92: 
   93: void get_winsize()
   94: {
   95: #ifdef TIOCGWINSZ
   96:   struct winsize size;
   97:   
   98:   if (ioctl (1, TIOCGWINSZ, (char *) &size) >= 0) {
   99:     rows = size.ws_row;
  100:     cols = size.ws_col;
  101:   }
  102: #else
  103:   char *s;
  104:   if ((s=getenv("LINES"))) {
  105:     rows=atoi(s);
  106:     if (rows==0)
  107:       rows=DEFAULTROWS;
  108:   }
  109:   if ((s=getenv("COLUMNS"))) {
  110:     rows=atoi(s);
  111:     if (rows==0)
  112:       cols=DEFAULTCOLS;
  113:   }
  114: #endif
  115: }
  116: 
  117: #ifdef SIGWINCH
  118: static void change_winsize(int sig)
  119: {
  120:   signal(sig,change_winsize);
  121: #ifdef TIOCGWINSZ
  122:   get_winsize();
  123: #endif
  124: }
  125: #endif
  126: 
  127: void install_signal_handler(int sig, void (*simple_handler)(), void (*complex_handler)())
  128:      /* installs signal handler for sig. If the system has the
  129:         necessary support, complex_handler will be invoked upon
  130:         receipt of a signal, otherwise simple_handler. */
  131: {
  132: #ifdef SA_SIGINFO
  133:   struct sigaction action;
  134: 
  135:   action.sa_handler=simple_handler;
  136:   action.sa_sigaction=complex_handler;
  137:   sigemptyset(&action.sa_mask);
  138:   action.sa_flags=SA_SIGINFO; /* use complex_handler */
  139:   sigaction(sig, action, NULL);
  140: #else
  141:   /* ANSI C */
  142:   signal(sig,simple_handler);
  143: #endif
  144: }
  145: 
  146: void install_signal_handlers(void)
  147: {
  148: 
  149: #if 0
  150: /* these signals are handled right by default, no need to handle them;
  151:    they are listed here just for fun */
  152:   static short sigs_to_default [] = {
  153: #ifdef SIGCHLD
  154:     SIGCHLD,
  155: #endif
  156: #ifdef SIGINFO
  157:     SIGINFO,
  158: #endif
  159: #ifdef SIGIO
  160:     SIGIO,
  161: #endif
  162: #ifdef SIGLOST
  163:     SIGLOST,
  164: #endif
  165: #ifdef SIGKILL
  166:     SIGKILL,
  167: #endif
  168: #ifdef SIGSTOP
  169:     SIGSTOP,
  170: #endif
  171: #ifdef SIGPWR
  172:     SIGPWR,
  173: #endif
  174: #ifdef SIGMSG
  175:     SIGMSG,
  176: #endif
  177: #ifdef SIGDANGER
  178:     SIGDANGER,
  179: #endif
  180: #ifdef SIGMIGRATE
  181:     SIGMIGRATE,
  182: #endif
  183: #ifdef SIGPRE
  184:     SIGPRE,
  185: #endif
  186: #ifdef SIGVIRT
  187:     SIGVIRT,
  188: #endif
  189: #ifdef SIGGRANT
  190:     SIGGRANT,
  191: #endif
  192: #ifdef SIGRETRACT
  193:     SIGRETRACT,
  194: #endif
  195: #ifdef SIGSOUND
  196:     SIGSOUND,
  197: #endif
  198: #ifdef SIGSAK
  199:     SIGSAK,
  200: #endif
  201: #ifdef SIGTSTP
  202:     SIGTSTP,
  203: #endif
  204: #ifdef SIGTTIN
  205:     SIGTTIN,
  206: #endif
  207: #ifdef SIGTTOU
  208:     SIGTTOU,
  209: #endif
  210: #ifdef SIGSTKFLT
  211:     SIGSTKFLT,
  212: #endif
  213: #ifdef SIGUNUSED
  214:     SIGUNUSED,
  215: #endif
  216:   };
  217: #endif
  218: 
  219:   static short sigs_to_throw [] = {
  220: #ifdef SIGBREAK
  221:     SIGBREAK,
  222: #endif
  223: #ifdef SIGINT
  224:     SIGINT,
  225: #endif
  226: #ifdef SIGILL
  227:     SIGILL,
  228: #endif
  229: #ifdef SIGEMT
  230:     SIGEMT,
  231: #endif
  232: #ifdef SIGFPE
  233:     SIGFPE,
  234: #endif
  235: #ifdef SIGIOT
  236:     SIGIOT,
  237: #endif
  238: #ifdef SIGSEGV
  239:     SIGSEGV,
  240: #endif
  241: #ifdef SIGALRM
  242:     SIGALRM,
  243: #endif
  244: #ifdef SIGPIPE
  245:     SIGPIPE,
  246: #endif
  247: #ifdef SIGPOLL
  248:     SIGPOLL,
  249: #endif
  250: #ifdef SIGPROF
  251:     SIGPROF,
  252: #endif
  253: #ifdef SIGBUS
  254:     SIGBUS,
  255: #endif
  256: #ifdef SIGSYS
  257:     SIGSYS,
  258: #endif
  259: #ifdef SIGTRAP
  260:     SIGTRAP,
  261: #endif
  262: #ifdef SIGURG
  263:     SIGURG,
  264: #endif
  265: #ifdef SIGUSR1
  266:     SIGUSR1,
  267: #endif
  268: #ifdef SIGUSR2
  269:     SIGUSR2,
  270: #endif
  271: #ifdef SIGVTALRM
  272:     SIGVTALRM,
  273: #endif
  274: #ifdef SIGXFSZ
  275:     SIGXFSZ,
  276: #endif
  277:   };
  278:   static short sigs_to_quit [] = {
  279: #ifdef SIGHUP
  280:     SIGHUP,
  281: #endif
  282: #ifdef SIGQUIT
  283:     SIGQUIT,
  284: #endif
  285: #ifdef SIGABRT
  286:     SIGABRT,
  287: #endif
  288: #ifdef SIGTERM
  289:     SIGTERM,
  290: #endif
  291: #ifdef SIGXCPU
  292:     SIGXCPU,
  293: #endif
  294:   };
  295:   int i;
  296:   void (*throw_handler)() = die_on_signal ? graceful_exit : signal_throw;
  297: 
  298: #define DIM(X)		(sizeof (X) / sizeof *(X))
  299: /*
  300:   for (i = 0; i < DIM (sigs_to_ignore); i++)
  301:     signal (sigs_to_ignore [i], SIG_IGN);
  302: */
  303:   for (i = 0; i < DIM (sigs_to_throw); i++)
  304:     install_signal_handler(sigs_to_throw [i], throw_handler, throw_handler);
  305:   for (i = 0; i < DIM (sigs_to_quit); i++)
  306:     signal (sigs_to_quit [i], graceful_exit);
  307: #ifdef SIGCONT
  308:     signal (SIGCONT, termprep);
  309: #endif
  310: #ifdef SIGWINCH
  311:     signal (SIGWINCH, change_winsize);
  312: #endif
  313: }

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