/* Clif - A C-like Interpreter Framework Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 T. Hruz, L. Koren 1998 L. Koren This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * sig-lin.c * * Functions for framework interrupt handling. */ #include "global.h" #include "config.h" #include #include #include #include #include #include #define OFF(x, y) (x) & (~(y)) #define ON(x, y) (x) | (y) #define SPACE 0x20 #define NL '\n' int handler = 0; int handle_fd; struct termio term, term_initial; struct sigvec vec, ovec; RETSIGTYPE (*interrupt_handler) PROTO((int)); RETSIGTYPE interrupt_service PROTO((int)); void interrupt_register PROTO((void)); void term_restore PROTO((void)); RETSIGTYPE fatal_handler PROTO((int)); void fatal_handler_register PROTO((void)); extern jmp_buf jmpbuf; extern int error_count; /* * Registers interrupt handler. */ void interrupt_register () { interrupt_handler = interrupt_service; handle_fd = fileno (stdin); ioctl (handle_fd, TCGETA, &term); term_initial = term; term.c_cc[0] = 0x14; /* DC4 */ term.c_cc[5] = 0x12; /* DC2 */ ioctl (handle_fd, TCSETA, &term); vec.sv_handler = interrupt_handler; sigvec (SIGINT, &vec, &ovec); } /* * Asynchronous interrupt handler. */ RETSIGTYPE interrupt_service (signo) int signo; { #ifdef DEBUG_INTER printfx ("interrupt\n"); #endif if ((clif_interrupt_level > 0) || (!virtual_machine_suspended)) /* * Test of the virtual machine running and the level of a interrupt. * Interrupt is only accepted if the virtual machine is running. */ { #ifdef DEBUG_INTER printfx ("virtual machine is running, interrupt accepted\n"); #endif handler = 1; #ifdef HAVE_TIOCSTI ioctl (handle_fd, TIOCSTI, "\n"); #endif } return; } /* * Synchronous interrupt service. */ void interrupt_service_sync () { handler = 1; } /* * Restores setting of the terminal at the termination of Clif session. */ void term_restore () { ioctl (handle_fd, TCSETA, &term_initial); } RETSIGTYPE fatal_handler (signo) int signo; { if (signo != SIGFPE && signo != SIGSEGV) return; if (error_count) longjmp (jmpbuf, 1); { struct sigvec vec, ovec; vec.sv_handler = SIG_DFL; sigvec (signo, &vec, &ovec); } } void fatal_handler_register () { struct sigvec vec, ovec; vec.sv_handler = fatal_handler; if (sigvec (SIGFPE, &vec, &ovec) < 0) error_message (4004); if (sigvec (SIGSEGV, &vec, &ovec) < 0) error_message (4004); }