I opened a process(GNUplot) from C++ with the popen() function. When I Ctrl+C to terminate the process, GNUplot also receives SIGINT signal. I want to prevent this from happening as it has an unfavorable effect on what I do. (I prefer to handle the signal with my own signal handler function). How do I do that?
I plot using the plot '-'
command and iterate through all the values I want to plot. If the gnuplot receives SIGINT in the middle, it might stop plotting in the middle without completing the entire plot. I want it to complete the entire plot. This is the unfavorable effect I have.
popen(3) is running a new shell /bin/sh -c
on the command string.
The trap
builtin of the shell is handling signals; with an empty first argument it is ignoring it. So you could do
FILE* f = popen("trap '' TERM INT; gnuplot", "w");
BTW, POSIX trap
requires the signals to be named without SIG
prefix.
But that won't work, since gnuplot
itself is explicitly handling signals. There is no way to avoid that outside of gnuplot
. But take advantage of the free software nature of gnuplot
: download its source code, study it, and patch it to fit your bizarre needs. FWIW, SIGINT
and signal
appear in several places in the source code of gnuplot-5.0.5
.
However, you should consider (instead of using popen
) to call the low level system calls explicitly (fork
, execve
, pipe
, dup2
, waitpid
, signal
...). Read Advanced Linux Programming for details.
I strongly suspect that your question is an XY problem. You don't explain what "unfavorable effect" you actually want to avoid, and I am guessing you might avoid it otherwise.
I plot using the
plot '-'
command and iterate through all the values I want to plot. If the gnuplot receives SIGINT in the middle, it might stop plotting in the middle without completing the entire plot. I want it to complete the entire plot.
Actually you might set up two or three pipes (one for input, one for output, perhaps one for stderr, as seen on gnuplot
side) for gnuplot
. You need to go the low level system calls (explicit calls to pipe(2), fork(2) etc etc...). Your program should then have some event loop (probably based upon poll(2)...). And you would send a print "DONE"
command to gnuplot after every plot '-'
(don't forget to initialize with the appropriate set print '-'
or have another pipe for the stderr of gnuplot
). Your event loop would then catch that DONE
message to synchronize. Read also this.