Since on my Debian/Linux/Sid/x86-64 the command gnuplot --version
is outputting to stdout
the following line:
gnuplot 5.0 patchlevel 1
I would simply recommend
FILE* pipversion = popen("gnuplot --version", "r");
if (!pipversion) { perror("popen gnuplot"); exit(EXIT_FAILURE); };
char lineversion[128];
memset (lineversion, 0, sizeof(lineversion));
if (!fgets(lineversion, sizeof(lineversion), pipversion) {
perror("fgets"); exit(EXIT_FAILURE);
}
/// lineversion is like: gnuplot 5.0 patchlevel 1
int majvers=0, minvers=0, pos= -1;
char* restvers = NULL;
if (sscanf(lineversion, "gnuplot %d.%d %n", &majvers, &minvers, &pos) >= 2) {
assert (pos>=0);
restvers = lineversion+pos;
};
pclose(pipversion);
pipversion = NULL;
After that, majvers
contains the major version of gnuplot
(e.g. 5 in my case) and minvers
contains the minor version (e.g. 0), with restvers
being a suffix string (e.g. "patchlevel 1"
without the quotes).
There might be a potential race condition in the unusual and unlikely case that gnuplot
is updated between this popen
and the next one pipe = popen("gnuplot", "w");
. BTW, naming a variable pipe
is poor taste, since POSIX and Linux have the pipe(2) system call. But I don't think it is worth caring about that race condition.
BTW, you very probably want to replace your second pipe = popen("gnuplot", "w");
with an explicit double invocation of pipe(2) (followed by appropriate fork(2) & execvp(3) ...) to have both input and output pipes to gnuplot
, and manage them in your own event loop (probably around poll(2) ... see this & that answers).
(if you application has or uses its own event loop, in particular if it is a GUI application above Qt or GTK, you want to use the same event loop for the pipes; details are specific to the library providing that event loop: g_spawn_async_with_pipes & g_source_add_unix_fd for GTK, QProcess for Qt ... )
I don't have time to explain how to do that (double piping into command + event loop) in details, but the Advanced Linux Programming book (available online) has several chapters on that. Be aware that you need some event loop.