summaryrefslogtreecommitdiffstats
path: root/qooxdoo/source/perl/Qooxdoo/Services
diff options
context:
space:
mode:
authorTobi Oetiker <tobi@oetiker.ch>2008-06-02 22:03:33 +0200
committerTobi Oetiker <tobi@oetiker.ch>2008-06-02 22:03:33 +0200
commit8793d83042d5cf388a30ee5f8637fa6554334aa6 (patch)
treeca1d1a68cd3513f1eab9fa9a14559f687d233aae /qooxdoo/source/perl/Qooxdoo/Services
parent6b239270a134ef8f26d59a7ab9b35eeeeceb9c47 (diff)
downloadsmokeping-8793d83042d5cf388a30ee5f8637fa6554334aa6.tar.gz
smokeping-8793d83042d5cf388a30ee5f8637fa6554334aa6.tar.xz
initial support for mrt integration
Diffstat (limited to 'qooxdoo/source/perl/Qooxdoo/Services')
-rw-r--r--qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm128
1 files changed, 128 insertions, 0 deletions
diff --git a/qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm b/qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm
new file mode 100644
index 0000000..6aead46
--- /dev/null
+++ b/qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm
@@ -0,0 +1,128 @@
+package Qooxdoo::Services::Mtr;
+use strict;
+use POSIX qw(setsid :sys_wait_h);
+use Time::HiRes qw(usleep);
+
+sub GetAccessibility {
+ return "public";
+}
+
+sub launch {
+ my $error = shift;
+ $SIG{CHLD} = \&REAPER;
+ defined(my $pid = fork) or do { $error->set_error(101,"Can't fork: $!");return $error};
+ if ($pid){
+ open my $x, ">/tmp/mtr_session.$pid" or do {
+ $error->set_error(199,"Opening /tmp/mtr_session.$$: $!");
+ return $error;
+ };
+ close ($x);
+ return $pid;
+ }
+ chdir '/' or die "Can't chdir to /: $!";
+ open STDOUT, ">>/tmp/mtr_session.$$"
+ or die "Can't write to /tmp/mtr_session.$$: $!";
+ open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
+ setsid or die "Can't start a new session: $!";
+ open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
+ exec @_;
+}
+
+sub get_number {
+ my $error = shift;
+ my $data = shift;
+ $data = 'Undefined' unless defined $data;
+ if ($data =~ /^(\d+)$/){
+ return $1;
+ }
+ else {
+ $error->set_error(104,"Expected a number but got: $data");
+ return $error;
+ }
+}
+
+sub method_stop_mtr {
+ my $error = shift;
+ my $arg = shift;
+ my $handle = get_number($error,$arg);
+ return $handle if ref $handle;
+ my $data = "/tmp/mtr_session.".$handle;
+ if (-r $data){
+ warn "Sending kill $handle";
+ kill('KILL',$handle);
+ }
+}
+
+sub method_run_mtr
+{
+ my $error = shift;
+ my $arg = shift;
+ my $handle = get_number($error,$arg->{handle});
+ my $point = get_number($error,$arg->{point});
+ if ($arg->{host}){
+ my $delay = get_number($error,$arg->{delay});
+ return $delay if ref $delay;
+ my $rounds = get_number($error,$arg->{rounds});
+ return $rounds if ref $rounds;
+ $handle = launch ($error,"mtr","-4","--raw","--report-cycles=$rounds","--interval=$delay",$arg->{host});
+ $point = 0;
+ }
+ return $point if ref $point;
+ return $handle if ref $handle;
+ my $data = "/tmp/mtr_session.".$handle;
+ if (open my $fh,$data){
+ my $again;
+ my $size;
+ my $rounds = 0;
+ do {
+ $size = -s $fh;
+ # make sure we reap any zombi instances of mtr
+ # this is especially important when running with speedy of fastcgi
+ waitpid($handle,WNOHANG);
+ $again = kill(0, $handle);
+ usleep(1000*200) if $rounds;
+# print STDERR "$again, $handle, $size, $point\n";
+ $rounds ++;
+ } while ($again and $point >= $size);
+ if (seek $fh, $point,0){
+ my @array;
+ while (<$fh>){
+ if (not /^[a-z]\s/){
+ waitpid($handle,WNOHANG);
+ if (/Name or service not known/){
+ $error->set_error(108,"Unknown hostname.");
+ return $error;
+ }
+ else {
+ $error->set_error(107,"ERROR: $_. See $data for more information.");
+ return $error;
+ }
+ }
+ last unless /\n$/; # stop when we find an incomplete line
+ $point = tell($fh);
+ chomp;
+ my @line = split (/\s+/,$_);
+ push @array,\@line;
+ };
+ close $fh;
+ unlink $data unless $again;
+ return {
+ handle=>$handle,
+ point=>$point,
+ output=>\@array,
+ again=> $again,
+ }
+ }
+ else {
+ $error->set_error(102,"Seeking in mtr output to $point: $!");
+ return $error;
+ }
+ }
+ else {
+ $error->set_error(103,"Opening $data: $!");
+ return $error;
+ }
+}
+
+1;
+