Alien-Gnuplot
view release on metacpan or search on metacpan
lib/Alien/Gnuplot.pm view on Meta::CPAN
variable or make sure your PATH contains it. If you do not have
gnuplot, you can reinstall Alien::Gnuplot (and its installation
script will try to install gnuplot) or get it yourself from L<https://gnuplot.sourceforge.net/>.
};
}
##############################
# Execute the executable to make sure it's really gnuplot, and parse
# out its reported version. This is complicated by gnuplot's shenanigans
# with STDOUT and STDERR, so we fork and redirect everything to a file.
# The parent process gives the daughter 2 seconds to report progress, then
# kills it dead.
my($pid);
my ($undef, $file) = tempfile();
# Create command file
open FOO, ">${file}_gzinta";
print FOO "show version\nset terminal\n\n\n\n\n\n\n\n\n\nprint \"CcColors\"\nshow colornames\n\n\n\n\n\n\n\nprint \"FfFinished\"\nexit\n";
close FOO;
if($^O =~ /MSWin32/i) {
if( $exec_path =~ m/([\"\*\?\<\>\|])/ ) {
die "Alien::Gnuplot: Invalid character '$1' in path to gnuplot -- I give up" ;
}
# Microsoft Windows sucks at IPC (and many other things), so
# use "system" instead of civilized fork/exec.
# This leaves us vulnerable to gnuplot itself hanging, but
# sidesteps the problem of waitpid hanging on Strawberry Perl.
open FOO, ">&STDOUT";
open BAR, ">&STDERR";
open STDOUT,">$file";
open STDERR,">$file";
system(qq{"$exec_path" < ${file}_gzinta});
open STDOUT,">&FOO";
open STDERR,">&BAR";
close FOO;
close BAR;
} else {
$pid = fork();
if(defined($pid)) {
if(!$pid) {
# daughter
open BAR, ">&STDERR"; # preserve stderr
eval {
open STDOUT, ">$file";
open STDERR, ">&STDOUT";
open STDIN, "<${file}_gzinta";
seek STDIN, 0, SEEK_SET;
no warnings;
exec($exec_path);
print BAR "Execution of $exec_path failed!\n";
exit(1);
};
print STDERR "Alien::Gnuplot: Unknown problems spawning '$exec_path' to probe gnuplot.\n";
exit(2); # there was a problem!
} else {
# parent
# Assume we're more POSIX-compliant...
if($DEBUG) { print "waiting for pid $pid (up to 20 iterations of 100ms)"; flush STDOUT; }
for (1..20) {
if($DEBUG) { print "."; flush STDOUT; }
if(waitpid($pid,WNOHANG)) {
$pid=0;
last;
}
usleep(1e5);
}
if($DEBUG) { print "\n"; flush STDOUT; }
if($pid) {
if( $DEBUG) { print "gnuplot didn't complete. Killing it dead...\n"; flush STDOUT; }
kill 9,$pid; # zap
waitpid($pid,0); # reap
}
} #end of parent case
} else {
# fork returned undef - error.
die "Alien::Gnuplot: Couldn't fork to test gnuplot! ($@)\n";
}
}
##############################
# Read what gnuplot had to say, and clean up our mess...
open FOO, "<$file";
my @lines = <FOO>;
close FOO;
unlink $file;
unlink $file."_gzinta";
##############################
# Whew. Now parse out the 'GNUPLOT' and version number...
my $lines = join("", map { chomp $_; $_} @lines);
$lines =~ s/\s+G N U P L O T\s*// or die qq{
Alien::Gnuplot: the executable '$exec_path' appears not to be gnuplot,
or perhaps there was a problem running it. You can remove it or set
your GNUPLOT_BINARY variable to an actual gnuplot.
Raw output from Gnuplot:
$lines
};
$lines =~ m/Version (\d+\.\d+) (patchlevel (\d+))?/ or die qq{
Alien::Gnuplot: the executable file $exec_path claims to be gnuplot, but
I could not parse a version number from its output. Sorry, I give up.
Raw output from Gnuplot:
$lines
};
$version = $1;
$pl = $3;
$executable = $exec_path;
##############################
# Parse out available terminals and put them into the
# global list and hash.
@terms = ();
%terms = ();
my $reading_terms = 0;
( run in 4.100 seconds using v1.01-cache-2.11-cpan-96521ef73a4 )