Baggrundsprogram i Perl

No Comments

For at fejre at jeg endelig er kommet 1/3 af vejen igennem "Programming Perl", har jeg brugt lidt tid på at lave en skabelon, over et baggrundsprogram i Perl. Skabelonen kan hurtigt tilpasses, og har endda en sub-rutine til logging.

Programmet skulle være POSIX-compliant.
God fornøjelse.

#!/usr/bin/perl
 
# No shortcommings
use strict;
use warnings;
 
my ($pidfilefh, $logfilefh, $logstring, $time, $pid); # Variables to be used
my $break_loop = 0; # Controls the loop the child runs in
my $piddir = '/var/run'; # Dir for the pidfile
my $logging = 1; # 1 equels logging, 0 does not
my $logdir = '/var/log'; # Dir for logging
my $pname = 'parser'; # Name of the pidfile (appended .pid) and logfile (appended .log)
 
# root is needed
if ($< != 0) { die "Fatal: Not enough privilegies, root requiredn" }
# If another pidfile exists, then something should be checked
if (-e "$piddir/$pname.pid") { die "Fatal: pidfile already exits: $piddir/$pname.pidn" }
# If logging is active the logfile needs permissions of 0644
# if ($logging and -e "$logdir/$pname.log") {chmod 0644, "$logdir/$pname.log"}
 
# This block deamonizes the program
use POSIX qw(setsid);
chdir '/' or die "Fatal: Can not change dir to /: $!n";
close(STDIN); close(STDOUT); close(STDERR);
open STDIN, '<', '/dev/null' or die "Fatal: Can not read from /dev/null: $!n";
open STDOUT, '>>', '/dev/null' or die "Fatal: Can not write to /dev/null: $!n";
open STDERR, '>>', '/dev/null' or die "Fatal: Can not write to /dev/null: $!n";
defined($pid = fork) or die "Fatal: Can not fork: $!n";
exit if $pid;
umask 0;
 
# Interception of signals can insure a clean shutdown
$SIG{INT} = $SIG{TERM} = $SIG{HUP} = &ipc;
 
# The logging subroutine takes 1 argument and logs it to file
logging(" --- Starting with PID $$ --- ");
 
# Time to write the pidfile and set proper permissions
open($pidfilefh, '>', "$piddir/$pname.pid") or die "Fatal: Can not create $piddir/$pname.pid: $! n";
print $pidfilefh "$$n" or die "Fatal: Can not write to $piddir/$pname.pid: $!";
close($pidfilefh);
chmod 0644, "$piddir/$pname.pid" or die "Fatal: Can not set permissions for $piddir/$pname.pid: $! n";
 
# The actual work the deamon will be doing
until($break_loop) {
logging("The current PID is: $$");
sleep(3);
}
 
# Subroutine which enables logging
sub logging {
open($logfilefh, '>>', "$logdir/$pname.log") or die "Fatal: Can not open logfile: $!";
my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
printf $logfilefh "%2d/%2d-%4d %2d:%02d:%02d - @_n",
$mday, $mon, $year+1900, $hour, $min, $sec;
close($logfilefh);
}
 
# A recived signal breaks the loop and starts a clean shutdown
sub ipc {
$break_loop = 1;
logging("Called by @_, exiting...");
}
 
# The very last things to do during a clean shutdown
END {
unlink "$piddir/$pname.pid";
}
exit;

\\

Comments are closed for this post