From b48224e514d375aa8e317118b35993c0d46adf2f Mon Sep 17 00:00:00 2001 From: Giles Atkinson <“gatk555@gmail.com”> Date: Mon, 4 Nov 2024 19:15:29 +0000 Subject: [PATCH] Improve the behaviour of ngspice when run in the background on a Unix-like OS with job control. The progress ticker is suppressed for a command like "ngspice some_circuit.cir &" so the terminal remains usuable while the simulation runs. --- src/frontend/outitf.c | 10 +++++----- src/frontend/signal_handler.c | 29 ++++++++++++++++++++++++----- src/frontend/signal_handler.h | 1 + src/main.c | 4 +++- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index 35bb0d1ca..87329841d 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -635,7 +635,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) every quarter of a second, to give some feedback without using too much CPU time */ #ifndef HAS_WINGUI - if (!orflag && !ft_norefprint) { + if (!orflag && !ft_norefprint && !cp_background) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { fprintf(stdout, " Reference value : % 12.5e\r", @@ -649,7 +649,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) else { /* And the same for a non-complex (real) value */ fileAddRealValue(run->fp, run->binary, refValue->rValue); #ifndef HAS_WINGUI - if (!orflag && !ft_norefprint) { + if (!orflag && !ft_norefprint && !cp_background) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { fprintf(stdout, " Reference value : % 12.5e\r", @@ -744,7 +744,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr) variable just the same */ #ifndef HAS_WINGUI - if (!orflag && !ft_norefprint) { + if (!orflag && !ft_norefprint && !cp_background) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { if (run->isComplex) { @@ -1532,7 +1532,7 @@ InterpFileAdd(runDesc *run, IFvalue *refValue, IFvalue *valuePtr) interpolatenow = FALSE; } #ifndef HAS_WINGUI - if (!orflag && !ft_norefprint) { + if (!orflag && !ft_norefprint && !cp_background) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { fprintf(stdout, " Reference value : % 12.5e\r", @@ -1693,7 +1693,7 @@ InterpPlotAdd(runDesc *run, IFvalue *refValue, IFvalue *valuePtr) #endif #ifndef HAS_WINGUI - if (!orflag && !ft_norefprint) { + if (!orflag && !ft_norefprint && !cp_background) { currclock = clock(); if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) { fprintf(stdout, " Reference value : % 12.5e\r", diff --git a/src/frontend/signal_handler.c b/src/frontend/signal_handler.c index 4d4d6ec2c..581a3d16e 100644 --- a/src/frontend/signal_handler.c +++ b/src/frontend/signal_handler.c @@ -2,7 +2,6 @@ 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. */ @@ -18,6 +17,10 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "signal_handler.h" #include "plotting/graf.h" +#ifdef SIGTTIN +#include +#endif + #ifdef HAS_WINGUI void winmessage(char* new_msg); #endif @@ -138,6 +141,23 @@ sigttio(void) (void) kill(getpid(), SIGTSTP); /* This should stop us */ } } + +/* Is this a background process? */ + +void test_background(void) +{ + pid_t terminal_group; + int tty; + + tty = open("/dev/tty", O_RDONLY); + if (tty < 0) { + cp_background = TRUE; // No controlling terminal, so "in background". + return; + } + terminal_group = tcgetpgrp(tty); // Posix 2001, so portable. + close(tty); + cp_background = (terminal_group != getpgrp()); +} #endif /* This should give a new prompt if cshpar is waiting for input. */ @@ -148,10 +168,8 @@ void sigstop(void) { gr_clean(); - if (!cp_background) { - (void) signal(SIGTSTP, SIG_DFL); - (void) kill(getpid(), SIGTSTP); /* This should stop us */ - } + (void) signal(SIGTSTP, SIG_DFL); + (void) kill(getpid(), SIGTSTP); /* This should stop us */ } @@ -159,6 +177,7 @@ void sigcont(void) { (void) signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop); + test_background(); if (cp_cwait) LONGJMP(jbuf, 1); } diff --git a/src/frontend/signal_handler.h b/src/frontend/signal_handler.h index 66168d818..611de12de 100644 --- a/src/frontend/signal_handler.h +++ b/src/frontend/signal_handler.h @@ -16,6 +16,7 @@ void sigbus(void); void sigsegv(void); void sigsegvsh(void); void sig_sys(void); +void test_background(void); extern JMP_BUF jbuf; diff --git a/src/main.c b/src/main.c index 698637cbb..6367b06ac 100644 --- a/src/main.c +++ b/src/main.c @@ -704,7 +704,7 @@ app_rl_readlines(void) cp_cwait = TRUE; app_event_func(); // Direct call to process X11 input. - } + } else #endif cp_cwait = TRUE; line = readline(cp_background ? NULL : prompt()); @@ -1213,10 +1213,12 @@ int main(int argc, char **argv) #ifdef SIGTSTP signal(SIGTSTP, (SIGNAL_FUNCTION) sigstop); + signal(SIGCONT, (SIGNAL_FUNCTION) sigcont); #endif #ifdef SIGTTIN signal(SIGTTIN, (SIGNAL_FUNCTION) sigttio); signal(SIGTTOU, (SIGNAL_FUNCTION) sigttio); + test_background(); // Process started in the background? #endif }