Annotation of gforth/engine/signals.c, revision 1.2

1.1       anton       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
1.2     ! anton      33: /* #include <asm/signal.h> */
        !            34: #include <signal.h>
1.1       anton      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: 
1.2     ! anton     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)
1.1       anton     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;
1.2     ! anton     296:   void (*throw_handler)() = die_on_signal ? graceful_exit : signal_throw;
1.1       anton     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++)
1.2     ! anton     304:     install_signal_handler(sigs_to_throw [i], throw_handler, throw_handler);
1.1       anton     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>