2000-04-27 22:03:57 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
|
|
|
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|
|
|
|
**********/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The signal routines for spice 3 and nutmeg.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "ngspice.h"
|
|
|
|
|
#include "ifsim.h"
|
|
|
|
|
#include "iferrmsg.h"
|
|
|
|
|
#include "cpdefs.h"
|
|
|
|
|
#include "ftedefs.h"
|
|
|
|
|
#include "ftedev.h"
|
|
|
|
|
#include <setjmp.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include "signal_handler.h"
|
|
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
#ifdef HAVE_GNUREADLINE
|
|
|
|
|
/* Added GNU Readline Support 11/3/97 -- Andrew Veliath <veliaa@rpi.edu> */
|
|
|
|
|
/* from spice3f4 patch to ng-spice. jmr */
|
|
|
|
|
#include <readline/readline.h>
|
|
|
|
|
#include <readline/history.h>
|
|
|
|
|
#endif
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2005-05-07 01:43:46 +02:00
|
|
|
#ifdef HAVE_BSDEDITLINE
|
|
|
|
|
/* SJB added edit line support 2005-05-05 */
|
|
|
|
|
#include <editline/readline.h>
|
|
|
|
|
#endif /* HAVE_BSDEDITLINE */
|
|
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
extern sigjmp_buf jbuf;
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
/* The (void) signal handlers... SIGINT is the only one that gets reset (by
|
|
|
|
|
* cshpar) so it is global. They are ifdef BSD because of the sigmask
|
|
|
|
|
* stuff in sigstop. We set the interrupt flag and return if ft_setflag
|
|
|
|
|
* is TRUE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern pid_t getpid (void);
|
|
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
/* invoke this function upon keyboard interrupt */
|
2000-04-27 22:03:57 +02:00
|
|
|
RETSIGTYPE
|
|
|
|
|
ft_sigintr(void)
|
|
|
|
|
{
|
2004-01-10 22:39:36 +01:00
|
|
|
/* fprintf (cp_err, "Received interrupt. Handling it . . . . .\n"); */
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
/* Reinstall ft_signintr as the signal handler. */
|
|
|
|
|
(void) signal( SIGINT, (SIGNAL_FUNCTION) ft_sigintr );
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
gr_clean(); /* Clean up plot window */
|
2000-04-27 22:03:57 +02:00
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
if (ft_intrpt) /* check to see if we're being interrupted repeatedly */
|
|
|
|
|
fprintf(cp_err, "Interrupted again (ouch)\n");
|
2000-04-27 22:03:57 +02:00
|
|
|
else {
|
2004-01-10 22:39:36 +01:00
|
|
|
fprintf(cp_err, "Interrupted once . . .\n");
|
2000-04-27 22:03:57 +02:00
|
|
|
ft_intrpt = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2004-01-10 22:39:36 +01:00
|
|
|
if (ft_setflag) {
|
|
|
|
|
return; /* just return without aborting simulation if ft_setflag = TRUE */
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-07 01:43:46 +02:00
|
|
|
/* sjb - what to do for editline???
|
|
|
|
|
The following are not supported in editline */
|
|
|
|
|
#if defined(HAVE_GNUREADLINE)
|
2004-01-10 22:39:36 +01:00
|
|
|
/* Clean up readline after catching signals */
|
2005-05-07 01:43:46 +02:00
|
|
|
/* One or all of these might be superfluous */
|
2004-01-10 22:39:36 +01:00
|
|
|
(void) rl_free_line_state();
|
|
|
|
|
(void) rl_cleanup_after_signal();
|
|
|
|
|
(void) rl_reset_after_signal();
|
2005-05-07 01:43:46 +02:00
|
|
|
#endif /* defined(HAVE_GNUREADLINE) || defined(HAVE_BSDEDITLINE) */
|
2004-01-10 22:39:36 +01:00
|
|
|
|
|
|
|
|
/* To restore screen after an interrupt to a plot for instance */
|
2000-04-27 22:03:57 +02:00
|
|
|
cp_interactive = TRUE;
|
2004-01-10 22:39:36 +01:00
|
|
|
cp_resetcontrol();
|
|
|
|
|
|
|
|
|
|
/* here we jump to the start of command processing in main() after resetting everything. */
|
|
|
|
|
siglongjmp(jbuf, 1);
|
|
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
2004-01-10 22:39:36 +01:00
|
|
|
|
2000-04-27 22:03:57 +02:00
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sigfloat(int sig, int code)
|
|
|
|
|
{
|
|
|
|
|
gr_clean();
|
|
|
|
|
fperror("Error", code);
|
|
|
|
|
rewind(cp_out);
|
|
|
|
|
(void) signal( SIGFPE, (SIGNAL_FUNCTION) sigfloat );
|
2004-01-10 22:39:36 +01:00
|
|
|
siglongjmp(jbuf, 1);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This should give a new prompt if cshpar is waiting for input. */
|
|
|
|
|
|
|
|
|
|
# ifdef SIGTSTP
|
|
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sigstop(void)
|
|
|
|
|
{
|
|
|
|
|
gr_clean();
|
|
|
|
|
cp_ccon(FALSE);
|
|
|
|
|
(void) signal(SIGTSTP, SIG_DFL);
|
|
|
|
|
(void) kill(getpid(), SIGTSTP); /* This should stop us */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sigcont(void)
|
|
|
|
|
{
|
|
|
|
|
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop);
|
|
|
|
|
if (cp_cwait)
|
2004-01-10 22:39:36 +01:00
|
|
|
siglongjmp(jbuf, 1);
|
2000-04-27 22:03:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# endif
|
|
|
|
|
|
|
|
|
|
/* Special (void) signal handlers. */
|
|
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sigill(void)
|
|
|
|
|
{
|
|
|
|
|
fprintf(cp_err, "\ninternal error -- illegal instruction\n");
|
|
|
|
|
fatal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sigbus(void)
|
|
|
|
|
{
|
|
|
|
|
fprintf(cp_err, "\ninternal error -- bus error\n");
|
|
|
|
|
fatal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sigsegv(void)
|
|
|
|
|
{
|
|
|
|
|
fprintf(cp_err, "\ninternal error -- segmentation violation\n");
|
|
|
|
|
fatal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RETSIGTYPE
|
|
|
|
|
sig_sys(void)
|
|
|
|
|
{
|
|
|
|
|
fprintf(cp_err,
|
|
|
|
|
"\ninternal error -- bad argument to system call\n");
|
|
|
|
|
fatal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|