From 60791062ac4f87b599e4fa12a7dfadf71d072c29 Mon Sep 17 00:00:00 2001 From: Stefan Schippers Date: Mon, 31 Aug 2020 21:24:03 +0200 Subject: [PATCH] added -b/--batch cmd option (__unix__ only) to detach xschem completely from console --- doc/manpages/xschem.1.in | 4 ++++ doc/xschem_man/run_xschem.html | 1 + src/globals.c | 2 +- src/main.c | 32 ++++++++++++++++++++++++++++---- src/options.c | 3 +++ src/xinit.c | 6 +++++- src/xschem.h | 2 +- src/xschem.help | 1 + 8 files changed, 44 insertions(+), 7 deletions(-) diff --git a/doc/manpages/xschem.1.in b/doc/manpages/xschem.1.in index 4fa3f078..641166c3 100644 --- a/doc/manpages/xschem.1.in +++ b/doc/manpages/xschem.1.in @@ -38,6 +38,10 @@ hierarchical representation of circuits with a top down approach. Print help and exit. .TP +.B -n, --batch +Detach xschem from console. +.TP + .B -n, --netlist Do a netlist of the given schematic cell. .TP diff --git a/doc/xschem_man/run_xschem.html b/doc/xschem_man/run_xschem.html index 42ea25a7..e2e08dd3 100644 --- a/doc/xschem_man/run_xschem.html +++ b/doc/xschem_man/run_xschem.html @@ -47,6 +47,7 @@ user:~$ xschem .../xschem_library/examples/0_examples_top.sch usage: xschem [options] [schematic | symbol ] Options: -h --help Print this help. + -b --batch Detach Xschem from console. -n --netlist Do a netlist of the given schematic cell. -v --version Print version information and exit. -V --vhdl Set netlist type to VHDL. diff --git a/src/globals.c b/src/globals.c index 1eb50303..a4783ef5 100644 --- a/src/globals.c +++ b/src/globals.c @@ -268,7 +268,7 @@ struct wireentry *wiretable[NBOXES][NBOXES]; struct instentry *insttable[NBOXES][NBOXES]; size_t get_tok_value_size; size_t get_tok_size; - +int batch_mode = 0; /* no tcl console if set; batch mode */ #ifdef HAS_CAIRO cairo_surface_t *sfc, *save_sfc; diff --git a/src/main.c b/src/main.c index cc427134..7ebc1580 100644 --- a/src/main.c +++ b/src/main.c @@ -26,10 +26,10 @@ #endif void sig_handler(int s){ - #ifndef IN_MEMORY_UNDO +#ifndef IN_MEMORY_UNDO char emergency_prefix[PATH_MAX]; const char *emergency_dir; - #endif +#endif /* 20150410 */ if(s==SIGINT) { @@ -37,7 +37,7 @@ void sig_handler(int s){ return; } - #ifndef IN_MEMORY_UNDO +#ifndef IN_MEMORY_UNDO /* 20180923 no more mkdtemp */ my_snprintf(emergency_prefix, S(emergency_prefix), "xschem_emergencysave_%s_", skip_dir(schematic[currentsch])); @@ -51,7 +51,7 @@ void sig_handler(int s){ fprintf(errfp, "rename dir %s to %s failed\n", undo_dirname, emergency_dir); } fprintf(errfp, "EMERGENCY SAVE DIR: %s\n", emergency_dir); - #endif +#endif fprintf(errfp, "\nFATAL: signal %d\n", s); fprintf(errfp, "while editing: %s\n", skip_dir(schematic[currentsch])); exit(EXIT_FAILURE); @@ -84,6 +84,30 @@ int main(int argc, char **argv) if(debug_var>=1 && !has_x) fprintf(errfp, "main(): no DISPLAY set, assuming no X available\n"); +/* detach from console (fork a child and close std file descriptors) */ +#ifdef __unix__ + if(batch_mode) { + pid_t pid = fork(); + if(pid < 0) { + fprintf(errfp, "main(): fork() failed\n"); + exit(EXIT_FAILURE); + } + if(pid == 0) { + /* The child becomes the daemon. */ + /* Detach all standard I/O descriptors */ + close(0); /* stdin */ + close(1); /* stdout */ + close(2); /* stderr */ + setsid(); /* new session */ + /* Ok, now detached */ + } + else { + /* terminate parent */ + exit(0); + } + } +#endif + if(has_x) Tk_Main(1, argv, Tcl_AppInit); else Tcl_Main(1, argv, Tcl_AppInit); return 0; diff --git a/src/options.c b/src/options.c index be2fc981..30793e59 100644 --- a/src/options.c +++ b/src/options.c @@ -129,6 +129,9 @@ void check_opt(char *opt, char *optval, int type) dbg(1, "process_options(): set netlist type to verilog\n"); netlist_type=CAD_VERILOG_NETLIST; + } else if( (type == SHORT && *opt == 'b') || (type == LONG && !strcmp("batch", opt)) ) { + batch_mode = 1; + } else if( (type == SHORT && *opt == 'v') || (type == LONG && !strcmp("version", opt)) ) { print_version(); diff --git a/src/xinit.c b/src/xinit.c index 3d4f00e9..343282b6 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -1454,7 +1454,11 @@ int Tcl_AppInit(Tcl_Interp *inter) /* */ - if(!no_readline) { + if( +#ifdef __unix__ + !batch_mode && +#endif + !no_readline) { tcleval( "if {![catch {package require tclreadline}]} " "{::tclreadline::readline customcompleter completer; ::tclreadline::Loop }" ) ; } diff --git a/src/xschem.h b/src/xschem.h index a2d448db..bc4a2355 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -674,7 +674,7 @@ extern double mx_double_save, my_double_save; /* 20070322 */ extern struct instentry *insttable[NBOXES][NBOXES]; extern size_t get_tok_value_size; extern size_t get_tok_size; - +extern int batch_mode; /* no TCL console */ /* functions */ extern void dbg(int level, char *fmt, ...); extern void here(void); diff --git a/src/xschem.help b/src/xschem.help index ab7884b8..9308040b 100644 --- a/src/xschem.help +++ b/src/xschem.help @@ -1,6 +1,7 @@ usage: xschem [options] [schematic | symbol ] Options: -h --help Print this help. + -b --batch Detach Xschem from console. -n --netlist Do a netlist of the given schematic cell. -v --version Print version information and exit. -V --vhdl Set netlist type to VHDL.