/*
* The Spar Library - a maths applications framework
* Copyright (C) 2000,2001 Davide Angelocola <davide178@inwind.it>
*
* 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 <spar/sl_application.h>
#include <stdio.h>
#if defined (HAVE_TERMIO_H)
#define TERMINAL_SUPPORT 1
#include <termio.h>
#elif defined (HAVE_TERMIOS_H)
#define TERMINAL_SUPPORT 1
#include <termios.h>
#elif defined (HAVE_TERMCAP_H)
#define TERMINAL_SUPPORT 1
#include <termcap.h>
#else
#define TERMINAL_SUPPORT 0
#endif
#include <signal.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1