Browse Source
If ngSpice_Command(NULL) is sent to shared ngspice,
If ngSpice_Command(NULL) is sent to shared ngspice,
the internal control structure memory is freed.pre-master-46
5 changed files with 195 additions and 191 deletions
-
16src/frontend/control.c
-
356src/frontend/signal_handler.c
-
2src/frontend/vectors.c
-
2src/include/ngspice/cpextern.h
-
10src/sharedspice.c
@ -1,178 +1,178 @@ |
|||||
/********** |
|
||||
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/ngspice.h" |
|
||||
#include "ngspice/ifsim.h" |
|
||||
#include "ngspice/iferrmsg.h" |
|
||||
#include "ngspice/cpdefs.h" |
|
||||
#include "ngspice/ftedefs.h" |
|
||||
#include "ngspice/ftedev.h" |
|
||||
#include <setjmp.h> |
|
||||
#include <signal.h> |
|
||||
#include "signal_handler.h" |
|
||||
#include "plotting/graf.h" |
|
||||
|
|
||||
#ifdef HAS_WINGUI |
|
||||
void winmessage(char* new_msg); |
|
||||
#endif |
|
||||
|
|
||||
#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 |
|
||||
|
|
||||
#ifdef HAVE_BSDEDITLINE |
|
||||
/* SJB added edit line support 2005-05-05 */ |
|
||||
#include <editline/readline.h> |
|
||||
#endif /* HAVE_BSDEDITLINE */ |
|
||||
|
|
||||
JMP_BUF jbuf; |
|
||||
|
|
||||
/* 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. |
|
||||
*/ |
|
||||
|
|
||||
|
|
||||
/* The purpose of ft_sigintr_cleanup() is to handle all processing of asynchronous |
|
||||
* signals which require user process context. Some kernel services are not |
|
||||
* allowed to be called from asynchronous signal handlers. (e.g. mutexes) |
|
||||
*/ |
|
||||
|
|
||||
void |
|
||||
ft_sigintr_cleanup(void) |
|
||||
{ |
|
||||
gr_clean(); /* Clean up plot window */ |
|
||||
|
|
||||
/* sjb - what to do for editline??? |
|
||||
The following are not supported in editline */ |
|
||||
#if defined(HAVE_GNUREADLINE) |
|
||||
/* Clean up readline after catching signals */ |
|
||||
/* One or all of these might be superfluous */ |
|
||||
(void) rl_free_line_state(); |
|
||||
(void) rl_cleanup_after_signal(); |
|
||||
(void) rl_reset_after_signal(); |
|
||||
#endif /* defined(HAVE_GNUREADLINE) || defined(HAVE_BSDEDITLINE) */ |
|
||||
|
|
||||
/* To restore screen after an interrupt to a plot for instance */ |
|
||||
cp_interactive = TRUE; |
|
||||
cp_resetcontrol(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/* invoke this function upon keyboard interrupt */ |
|
||||
RETSIGTYPE |
|
||||
ft_sigintr(void) |
|
||||
{ |
|
||||
static int interrupt_counter = 0; |
|
||||
|
|
||||
/* fprintf(cp_err, "Received interrupt. Handling it . . . . .\n"); */ |
|
||||
|
|
||||
/* Reinstall ft_signintr as the signal handler. */ |
|
||||
(void) signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr); |
|
||||
|
|
||||
if (ft_intrpt) { /* check to see if we're being interrupted repeatedly */ |
|
||||
fprintf(cp_err, "\nInterrupted again (ouch)\n"); |
|
||||
interrupt_counter++; |
|
||||
} else { |
|
||||
fprintf(cp_err, "\nInterrupted once . . .\n"); |
|
||||
ft_intrpt = TRUE; |
|
||||
interrupt_counter = 1; |
|
||||
} |
|
||||
|
|
||||
if (interrupt_counter >= 3) { |
|
||||
fprintf(cp_err, "\nKilling, since %d interrupts have been requested\n\n", interrupt_counter); |
|
||||
controlled_exit(1); |
|
||||
} |
|
||||
|
|
||||
if (ft_setflag) { |
|
||||
return; /* just return without aborting simulation if ft_setflag = TRUE */ |
|
||||
} |
|
||||
|
|
||||
/* here we jump to the start of command processing in main() after resetting everything. */ |
|
||||
LONGJMP(jbuf, 1); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
RETSIGTYPE |
|
||||
sigfloat(int sig, int code) |
|
||||
{ |
|
||||
NG_IGNORE(sig); |
|
||||
|
|
||||
fperror("Error", code); |
|
||||
rewind(cp_out); |
|
||||
(void) signal(SIGFPE, (SIGNAL_FUNCTION) sigfloat); |
|
||||
LONGJMP(jbuf, 1); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/* 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 */ |
|
||||
} |
|
||||
|
|
||||
|
|
||||
RETSIGTYPE |
|
||||
sigcont(void) |
|
||||
{ |
|
||||
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop); |
|
||||
if (cp_cwait) |
|
||||
LONGJMP(jbuf, 1); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
#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"); |
|
||||
#ifdef HAS_WINGUI |
|
||||
winmessage("Fatal error in NGSPICE"); |
|
||||
#endif |
|
||||
fatal(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
RETSIGTYPE |
|
||||
sig_sys(void) |
|
||||
{ |
|
||||
fprintf(cp_err, "\ninternal error -- bad argument to system call\n"); |
|
||||
fatal(); |
|
||||
} |
|
||||
|
/********** |
||||
|
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/ngspice.h" |
||||
|
#include "ngspice/ifsim.h" |
||||
|
#include "ngspice/iferrmsg.h" |
||||
|
#include "ngspice/cpdefs.h" |
||||
|
#include "ngspice/ftedefs.h" |
||||
|
#include "ngspice/ftedev.h" |
||||
|
#include <setjmp.h> |
||||
|
#include <signal.h> |
||||
|
#include "signal_handler.h" |
||||
|
#include "plotting/graf.h" |
||||
|
|
||||
|
#ifdef HAS_WINGUI |
||||
|
void winmessage(char* new_msg); |
||||
|
#endif |
||||
|
|
||||
|
#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 |
||||
|
|
||||
|
#ifdef HAVE_BSDEDITLINE |
||||
|
/* SJB added edit line support 2005-05-05 */ |
||||
|
#include <editline/readline.h> |
||||
|
#endif /* HAVE_BSDEDITLINE */ |
||||
|
|
||||
|
JMP_BUF jbuf; |
||||
|
|
||||
|
/* 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. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/* The purpose of ft_sigintr_cleanup() is to handle all processing of asynchronous |
||||
|
* signals which require user process context. Some kernel services are not |
||||
|
* allowed to be called from asynchronous signal handlers. (e.g. mutexes) |
||||
|
*/ |
||||
|
|
||||
|
void |
||||
|
ft_sigintr_cleanup(void) |
||||
|
{ |
||||
|
gr_clean(); /* Clean up plot window */ |
||||
|
|
||||
|
/* sjb - what to do for editline??? |
||||
|
The following are not supported in editline */ |
||||
|
#if defined(HAVE_GNUREADLINE) |
||||
|
/* Clean up readline after catching signals */ |
||||
|
/* One or all of these might be superfluous */ |
||||
|
(void) rl_free_line_state(); |
||||
|
(void) rl_cleanup_after_signal(); |
||||
|
(void) rl_reset_after_signal(); |
||||
|
#endif /* defined(HAVE_GNUREADLINE) || defined(HAVE_BSDEDITLINE) */ |
||||
|
|
||||
|
/* To restore screen after an interrupt to a plot for instance */ |
||||
|
cp_interactive = TRUE; |
||||
|
cp_resetcontrol(TRUE); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* invoke this function upon keyboard interrupt */ |
||||
|
RETSIGTYPE |
||||
|
ft_sigintr(void) |
||||
|
{ |
||||
|
static int interrupt_counter = 0; |
||||
|
|
||||
|
/* fprintf(cp_err, "Received interrupt. Handling it . . . . .\n"); */ |
||||
|
|
||||
|
/* Reinstall ft_signintr as the signal handler. */ |
||||
|
(void) signal(SIGINT, (SIGNAL_FUNCTION) ft_sigintr); |
||||
|
|
||||
|
if (ft_intrpt) { /* check to see if we're being interrupted repeatedly */ |
||||
|
fprintf(cp_err, "\nInterrupted again (ouch)\n"); |
||||
|
interrupt_counter++; |
||||
|
} else { |
||||
|
fprintf(cp_err, "\nInterrupted once . . .\n"); |
||||
|
ft_intrpt = TRUE; |
||||
|
interrupt_counter = 1; |
||||
|
} |
||||
|
|
||||
|
if (interrupt_counter >= 3) { |
||||
|
fprintf(cp_err, "\nKilling, since %d interrupts have been requested\n\n", interrupt_counter); |
||||
|
controlled_exit(1); |
||||
|
} |
||||
|
|
||||
|
if (ft_setflag) { |
||||
|
return; /* just return without aborting simulation if ft_setflag = TRUE */ |
||||
|
} |
||||
|
|
||||
|
/* here we jump to the start of command processing in main() after resetting everything. */ |
||||
|
LONGJMP(jbuf, 1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
RETSIGTYPE |
||||
|
sigfloat(int sig, int code) |
||||
|
{ |
||||
|
NG_IGNORE(sig); |
||||
|
|
||||
|
fperror("Error", code); |
||||
|
rewind(cp_out); |
||||
|
(void) signal(SIGFPE, (SIGNAL_FUNCTION) sigfloat); |
||||
|
LONGJMP(jbuf, 1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* 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 */ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
RETSIGTYPE |
||||
|
sigcont(void) |
||||
|
{ |
||||
|
(void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop); |
||||
|
if (cp_cwait) |
||||
|
LONGJMP(jbuf, 1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#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"); |
||||
|
#ifdef HAS_WINGUI |
||||
|
winmessage("Fatal error in NGSPICE"); |
||||
|
#endif |
||||
|
fatal(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
RETSIGTYPE |
||||
|
sig_sys(void) |
||||
|
{ |
||||
|
fprintf(cp_err, "\ninternal error -- bad argument to system call\n"); |
||||
|
fatal(); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue