/*
    UIT signals management file
    Copyright (c) 1993, 1994 Tudor Hulubei & Andrei Pitis

This file is part of UIT (UNIX Interactive Tools)

UIT 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.

UIT 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
UIT; see the file COPYING.  If not, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA.  */


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>

#include "signals.h"
#include "edit.h"
#include "tty.h"
#include "misc.h"


extern char *screen;
extern edit *edt;


int suspended = OFF;
int suspend_allowed = OFF;
int signals_status;
int UserHeartAttack;


void suspend(int signum)
{
    if (suspend_allowed)
    {
	suspended = ON;
	uitclock(OFF);
	tty_set_mode(TTY_CANONIC);
	tty_putscreen(screen);
	signal(SIGTSTP, SIG_DFL);
	kill(getpid(), SIGTSTP);
    }
    else
	signal(SIGTSTP, suspend);
}


void user_panic(int signum)
{
    signal(signum, user_panic);
    tcdrain(1);
    tcflush(0, TCIFLUSH);
    UserHeartAttack = 1; 
}


void fatal_signal(int signum)
{
    clean_up();

    switch (signum)
    {
	case SIGTERM:
	case SIGQUIT:

	    fprintf(stderr, "%s: got %s.\n",
	           program, ((signum == SIGTERM) ? "SIGTERM" : "SIGQUIT"));
	    break;

	case SIGSEGV:

	    fprintf(stderr, "%s: got SIGSEGV.\n", program);
	    goto ask_report;
	    break;

	case SIGHUP:

	    /* :-) */
	    fprintf(stderr, "%s: got SIGHUP.\n", program);
	    break;

	default:

	    fprintf(stderr,
	    	    "%s: got a stupid signal (%d). Unless it was a joke ...\n",
	    	    program, signum);
	  ask_report:
	    fprintf(stderr, "%s: please report to tudor@ulise.cs.pub.ro.\n",
	    	    program);
	    break;
    }

    exit(1);
}


void signals_dfl(void)
{
    signal(SIGTERM, SIG_DFL);
    signal(SIGQUIT, SIG_DFL);
    signal(SIGINT , SIG_DFL);
}


void signals(int status)
{
    signals_status = status;
    signal(SIGTERM, status == ON ? fatal_signal : SIG_IGN);
    signal(SIGQUIT, status == ON ? fatal_signal : SIG_IGN);
    signal(SIGINT , status == ON ? user_panic   : SIG_IGN);
}


void ignore_signals(void)
{
    signal(SIGILL,  SIG_IGN);
    signal(SIGTRAP, SIG_IGN);
    signal(SIGABRT, SIG_IGN);
    signal(SIGUSR1, SIG_IGN);
    signal(SIGUSR2, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGFPE,  SIG_IGN);
}


void restore_signals(void)
{
    signal(SIGILL,  SIG_DFL);
    signal(SIGTRAP, SIG_DFL);
    signal(SIGABRT, SIG_DFL);
    signal(SIGUSR1, SIG_DFL);
    signal(SIGUSR2, SIG_DFL);
    signal(SIGPIPE, SIG_DFL);
    signal(SIGFPE,  SIG_DFL);
}
