/* * The Spar Library - a maths applications framework * Copyright (C) 2000,2001 Davide Angelocola * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */ #include #include #if defined (HAVE_TERMIO_H) #define TERMINAL_SUPPORT 1 #include #elif defined (HAVE_TERMIOS_H) #define TERMINAL_SUPPORT 1 #include #elif defined (HAVE_TERMCAP_H) #define TERMINAL_SUPPORT 1 #include #else #define TERMINAL_SUPPORT 0 #endif #include #if (RETSIGTYPE == void) #define SIGHANDLER_RETURN return #else #define SIGHANDLER_RETURN return (signal) #endif typedef RETSIGTYPE (*_sighandler) (int); #define SL_SIGHANDLER(x) RETSIGTYPE (x) (int signal) extern void sl_application_exit (int _exit_code); /* * sl will install its own signal handlers for * o SIGINT (ctrl-C) * o SIGTERM * o SIGQUIT * o SIGALRM * o SIGTSTP */ SL_SIGHANDLER (_ignore_this_signal) { SIGHANDLER_RETURN; } SL_SIGHANDLER (_handle_this_signal) { sl_application_exit (0); SIGHANDLER_RETURN; } /* * Terminal support for this applications * * This code is always present because it clean the memory * on many signal interrupt (such as SIGINT, SIGSTOP, ecc) * and set some other terminal option (such as disable the * CTRL-D control char). */ static void _install_handler (void) { struct sigaction setup_action; sigset_t block_mask; /* * Setting the block mask */ sigemptyset (&block_mask); sigaddset (&block_mask, SIGINT); sigaddset (&block_mask, SIGQUIT); /* * Setting action handler */ setup_action.sa_handler = sl_application_exit; setup_action.sa_mask = block_mask; setup_action.sa_flags = 0; sigaction (SIGTSTP, &setup_action, 0); return; } static struct termios _old_term; static struct termios _new_term; void _restore_term (void) { tcsetattr (fileno (stdin), TCSANOW, &_old_term); } /* * Inits some terminal parameter such as: * o inibiths the use of CTRL-D key * o installs signals handlers * o saves the old terminal configuration */ void _init_term (void) { _install_handler (); /* * Setting signals handlers */ signal (SIGINT, _handle_this_signal); signal (SIGQUIT, _handle_this_signal); signal (SIGKILL, _handle_this_signal); signal (SIGTERM, _handle_this_signal); signal (SIGALRM, _ignore_this_signal); signal (SIGTSTP, _ignore_this_signal); #ifdef HAVE_TCGETATTR tcgetattr (fileno (stdin), &_old_term); _new_term = _old_term; _new_term.c_cc[VEOF] = 1; /* don't allow CTRL-D */ if ((tcsetattr (fileno (stdin), TCSAFLUSH, &_new_term)) < 0) { _restore_term (); sl_application_exit (SL_SUCCESS); } #else sl_writeln ("%s: %s: ", __FILE__, __FUNCTION__); sl_writeln ("Failed to change terminal attributes: tcgetattr() is missing."); sl_writeln ("CTRL-D not handled: beware from use this control key."); #endif return; }