/*********************************************************************** * * Copyright 2001, 2002, 2003 Free Software Foundation, Inc. * Written by Paolo Bonzini. * * This file is part of GNU Smalltalk. * * GNU Smalltalk 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, or (at your option) any later * version. * * GNU Smalltalk 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 * GNU Smalltalk; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***********************************************************************/ RETSIGTYPE interrupt_handler (int sig) { mst_Boolean is_serious_error = true; mst_Boolean in_c_code = !in_interpreter || !ip || _gst_gc_running; switch (sig) { case SIGUSR1: is_serious_error = false; _gst_set_signal_handler (sig, interrupt_handler); break; case SIGFPE: _gst_set_signal_handler (sig, interrupt_handler); return; case SIGINT: is_serious_error = false; if (!_gst_non_interactive) { _gst_set_signal_handler (sig, interrupt_handler); stop_executing ("userInterrupt"); return; } break; default: break; } if (sig != SIGUSR1) _gst_errorf ("%s", strsignal (sig)); if (!in_c_code) { /* Avoid recursive signals */ mst_Boolean save_in_interpreter = in_interpreter; in_interpreter = false; _gst_show_backtrace (); in_interpreter = save_in_interpreter; } else { if (is_serious_error) _gst_errorf ("Error occurred while not in byte code interpreter!!"); #ifdef HAVE_EXECINFO_H /* Don't print a backtrace, for example, if exiting during a compilation. */ if (ip || _gst_gc_running || is_serious_error || sig == SIGUSR1) { PTR array[11]; size_t size = backtrace (array, 11); backtrace_symbols_fd (array + 1, size, STDERR_FILENO); } #endif } if (sig == SIGUSR1) return; _gst_set_signal_handler (sig, SIG_DFL); raise (sig); } SigHandler _gst_set_signal_handler (int signum, SigHandler handlerFunc) { #ifdef _POSIX_VERSION /* If we are running on a POSIX-compliant system, then do things the POSIX way. */ struct sigaction act, o_act; act.sa_handler = handlerFunc; act.sa_flags = 0; sigemptyset (&act.sa_mask); sigaction (signum, &act, &o_act); return o_act.sa_handler; #else return signal (signum, handlerFunc); #endif }