#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use utf8;
my $base='../';
my $file=$base.'pid_file_%s.txt';
my $search=$base.'pid_file_*.txt';
my $sleep=5;
my $cgi=CGI->new();
$cgi->header(-type=>"text/html",-charset=>"UTF-8");
my $name=$ENV{SCRIPT_NAME} || $0;
my $action=$cgi->param('action') || 'list';
if($action eq 'start')
{
# KindProzess erzeuegn
local $SIG{CHLD}='IGNORE';
my $pid=fork();
# undef => fork funktionierte nicht
if(!defined($pid))
{ printerror($cgi,'Konnte Fork nicht erzeugen!'); }
# >0 => wir sind im Elternprozess
elsif($pid!=0)
{
printhtml($cgi,"Prozess $pid erzeugt",<<"EOH");
PID:$pid
Aktualisierung alle $sleep Sekunden
Zur Testseite
Status Anzeigen
Zur Übersicht
EOH
}
# 0 => wir sind im Kindprozess
else
{ runn_fork(sprintf($file,$$)); }
}
elsif($action eq 'stop')
{
# Kindprozess stoppen
my $pid=$cgi->param('pid');
my $time=stop_process($cgi,sprintf($file,$pid),$pid);
if($time>-1)
{
printhtml($cgi,"Prozess $pid Gestoppt",<<"EOH");
PID:$pid
TIME: $time SEC
Zur Übersicht
EOH
}
}
elsif($action eq 'status')
{
# Status eines bekannten Prozesses anzeigen
my $pid=$cgi->param('pid');
print_status($cgi,$pid,sprintf($file,$pid));
}
elsif($action eq 'list')
{
# Liste der überwachten Prozesse anzeigen
print_list($cgi,glob($search))
}
else
{ printerror($cgi,'Unkennte Aktion!'); }
########################################################################
########################################################################
sub stop_process
{
my $cgi=shift;
my $file=shift;
my $pid=shift;
my $time=0;
if(-f $file)
{
my @data=eval{local(@ARGV)=($file); <>};
my ($t1,$t2)=(shift(@data),pop(@data));
($t1)=$t1=~/\((\d+)\)/;
($t2)=$t2=~/\((\d+)\)/;
kill(15,$pid);
if(unlink($file))
{
return 0 unless($t1 && $t2);
return $t2-$t1;
}
else
{ printerror($cgi,"Kann $file nicht löschen! ($!)"); }
}
else
{ printerror($cgi,"Datei $file existiert nicht!"); }
return -1;
}
# Im Kindprozess ausführen
sub runn_fork
{
my $file=shift;
close(STDIN);
close(STDERR);
close(STDOUT);
# Signale Überwachen
local $SIG{TERM}=sub{
# Programm beenden
print2file($file,'SIGTERM');
exit();
};
local $SIG{KILL}=sub{
# Programm abbrechen
print2file($file,'SIGKILL');
exit();
};
local $SIG{XCPU}=sub{
# Wegen ungenügender Prozssorleistung abbrechen
print2file($file,'SIGXCPU');
exit();
};
local $SIG{XFSZ}=sub{
# Wegen Ungenügendem Speicherplatz (RAM/DISK)? abbrechen
print2file($file,'SIGXFSZ');
exit();
};
# datei anlegen
if(open(my $fh,'>',$file))
{ close($fh); }
print2file($file,'START') || exit;
while(1)
{
#abbruch wenn die datei nicht mehr zu öffen ist oder nicht mehr existiert!
print2file($file,'ALIVE') || exit;
sleep(5);
}
}
sub print2file
{
use Fcntl ':flock';
my $file=shift;
my $cmd=shift || '';
if($file && -f $file && open(my $fh,'>>',$file))
{
flock($fh, LOCK_EX);
print $fh $cmd.": ".localtime()." (".time.")\n";
close($fh);
return 1;
}
return 0;
}
########################################################################
sub print_list
{
my $cgi=shift;
my $list="\n";
my $name=$ENV{SCRIPT_NAME} || $0;
for my $file (@_)
{
my ($pid)=$file=~/(\d+)/;
my $status=psstatus($pid);
if($status eq 'STOPPED')
{
my $time=stop_process($cgi,$file,$pid);
return if($time == -1);
$list.=qq#
$ps
$dataweiter EOH } ######################################################################## ######################################################################## ######################################################################## sub printerror { my $cgi=shift; my $err=''; my $name=$ENV{SCRIPT_NAME} || $0; $err.="
\n$_\n\n" for(@_); printhtml($cgi,'ERROR',$err.qq#
(.+?)!sgc) { my $val=$1; my $symbol=sprintf('%s%08u',$unique,$cnt); $pre{$symbol}=$val; $body=~s!\Q
$val!$symbol!gs; $cnt++; } $body=~s/(^|\n)/$1 /gs; $body=~s!\s*($unique\d{8})!\n
$pre{$1}!g; if($cgi) { print $cgi->header(); } else { print "Content-Type: text/html\r\n\r\n"; } print <<"EOHTML";