#!/usr/bin/perl use strict; use Fcntl; my %conf=(timerstep=>5, fifo=>"./watchdog.add"); my @joblist=(); sub start_app($) { my $app_str=shift(@_); my $pid=fork(); exec($app_str) unless($pid); print "$0: Programm \"$app_str\" wurde mit der PID: \"$pid\" gestartet\n"; return $pid; } sub add_job($$$) { my ($app_str,$timeout,$pid)=@_; print "$0: Job hinzugefügt: \"$app_str\" PID=$pid, Timeout=$timeout\n"; push(@joblist,{app=>$app_str, time=>time(), timeout=>$timeout, pid=>$pid, running=>1}); } sub kill_job($) { my $pid=shift(@_); for my $job (@joblist) { if($job->{pid} == $pid) { $job->{running}=0; last; } } } sub test_jobs() { my $time=time(); for my $job (@joblist) { if($job->{time}+$job->{timeout} <= $time && $job->{running}>0) { my $ps=`ps -o "%c" --no-headers -p $job->{pid}`; chomp($ps); print "PS: $ps\n"; if( $ps eq $job->{app}) { print "$0: \"$job->{app}\" läuft noch nach $job->{timeout} Sekunden.\n"; } else { print "$0: \"$job->{app}\" wurde vorzeitzig beendet.\n"; } kill_job($job->{pid}); } } } ### Programm ### # fifo erzeugen unless(-p $conf{fifo}) { # kein FiFo if (-e $conf{fifo}) { die "$0: Werde $conf{fifo} nicht veändern!\n"; } else { require POSIX; POSIX::mkfifo($conf{fifo}, 0666) or die "mkfifo $conf{fifo} schlug fehl ($!)\n"; warn "$0: $conf{fifo} ist jetzt die Eingabedatei\n"; } } # Eingaben lesen while(1) { my $time=time(); my $in=""; eval { local $SIG{ALRM} = sub { die }; # timeout Zyklus setzen alarm($conf{timerstep}); eval { sysopen(FIFO, $conf{fifo}, O_RDONLY) or die "kann $conf{fifo} nicht lesen ($!)\n"; $in=join("",); chomp($in); close FIFO; }; # timeout aus. alarm(0); }; exit(0) if($in=~/^exit\s*$/s); print "IN: $in\n" if($in ne ""); my ($pid,$timeout,$app_str)=split(':',$in,3); if( $app_str ne '' && int($timeout)>0 ) { $pid=start_app($app_str) if($pid<=0); add_job($app_str,$timeout,$pid); } &test_jobs() if( $time+$conf{timerstep} <= time() ); }