diff options
| author | Paul Buetow <paul@buetow.org> | 2011-03-17 08:02:27 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2011-03-17 08:02:27 +0000 |
| commit | c0c2d506b4151a38178321e94276836dde52d169 (patch) | |
| tree | 0e867b0edf54b0950fd7ac05b61d276ad305c458 /lib | |
| parent | ee5e8bcb9b436c38f826304d49debf9d770bc877 (diff) | |
./lib and ./conf added.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Logger.pm | 40 | ||||
| -rw-r--r-- | lib/PerlDaemon.pl | 164 | ||||
| -rw-r--r-- | lib/RunModule.pm | 17 |
3 files changed, 221 insertions, 0 deletions
diff --git a/lib/Logger.pm b/lib/Logger.pm new file mode 100644 index 0000000..f6c16e8 --- /dev/null +++ b/lib/Logger.pm @@ -0,0 +1,40 @@ +package Logger; + +use Shell qw(mv); +use POSIX qw(strftime); + +$| = 1; + +sub new ($$) { + my ($class, $conf) = @_; + return bless { conf => $conf }, $class; +} + +sub logmsg ($$) { + my ($self, $msg) = @_; + my $conf = $self->{conf}; + my $logfile = $conf->{'daemon.logfile'}; + + open my $fh, ">>$logfile" or die "Can't write logfile $logfile: $!\n"; + print $fh localtime()." (PID $$): $msg\n"; + close $fh; +} + +sub err ($$) { + my ($self, $msg) = @_; + $self->logmsg($msg); + die "$msg\n"; +} + +sub rotatelog ($) { + my $self = shift; + my $conf = $self->{conf}; + my $logfile = $conf->{'daemon.logfile'}; + + $self->logmsg('Rotating logfile'); + + my $timestr = strftime "%Y%m%d-%H%M%S", localtime(); + mv($logfile, "$logfile.$timestr"); +} + +1; diff --git a/lib/PerlDaemon.pl b/lib/PerlDaemon.pl new file mode 100644 index 0000000..4e8ec3a --- /dev/null +++ b/lib/PerlDaemon.pl @@ -0,0 +1,164 @@ +#!/usr/bin/perl + +# Minimal PerlDaemon (c) 2011 Paul Buetow + +use strict; +use warnings; + +use Shell qw(mv); +use POSIX qw(setsid strftime); + +use Logger; +use RunModule; + +$| = 1; + +sub trimstr (@) { + my @str = + @_; + + for (@str) { + chomp; + s/^[\t\s]+//; + s/[\t\s]+$//; + } + + return @str; +} + +sub trunc ($) { + my $file = shift; + open my $fh, ">$file" or die "Can't write $file: $!\n"; + print $fh ''; + close $fh; +} + +sub checkpid ($) { + my $conf = shift; + my $pidfile = $conf->{'daemon.pidfile'}; + my $logger = $conf->{logger}; + + trunc $pidfile unless -f $pidfile; + + open my $fh, $pidfile or $logger->err("Can't read pidfile $pidfile: $!"); + my ($pid) = <$fh>; + close $fh; + + if (defined $pid) { + chomp $pid; + $logger->err("Process with pid $pid already running") if 0 < int $pid && kill 0, $pid; + } +} + +sub writepid ($) { + my $conf = shift; + my $logger = $conf->{logger}; + + my $pidfile = $conf->{'daemon.pidfile'}; + + open my $fh, ">$pidfile" or $logger->err("Can't write pidfile: $!"); + print $fh "$$\n"; + close $fh; +} + + +sub readconf ($) { + my $conffile = shift; + + open my $fh, $conffile or die "Can't read $conffile\n"; + my %conf; + + while (<$fh>) { + next if /^[\t\w]+#/; + s/#.*//; + + my ($key, $val) = trimstr split '=', $_, 2; + next unless defined $val; + + $conf{$key} = $val; + } + + close $fh; + + # Check + my $msg = 'Missing property:'; + + foreach (qw(wd loopinterval alivefile pidfile logfile)) { + my $key = "daemon.$_"; + die "$msg $key\n" unless exists $conf{$key}; + } + + return \%conf; +} + +sub daemonize ($) { + my $conf = shift; + my $logger = $conf->{logger}; + $logger->logmsg('Daemonizing...'); + + chdir $conf->{'daemon.wd'} or $logger->err("Can't chdir to wd: $!"); + + my $msg = 'Can\'t read /dev/null:'; + + open STDIN, '>/dev/null' or $logger->err("$msg $!"); + open STDOUT, '>/dev/null' or $logger->err("$msg $!"); + open STDERR, '>/dev/null' or $logger->err("$msg $!"); + + defined (my $pid = fork) or $logger->err("Can't fork: $!"); + exit if $pid; + + setsid or $logger->err("Can't start a new session: $!"); + + writepid $conf; + $logger->logmsg('Daemonizing completed'); +} + +sub sighandlers ($) { + my $conf = shift; + my $logger = $conf->{logger}; + + $SIG{TERM} = sub { + # On shutdown + $logger->logmsg('Received SIGTERM. Shutting down....'); + unlink $conf->{'daemon.pidfile'}; + exit 0; + }; + + $SIG{HUP} = sub { + # On logrotate + $logger->logmsg('Received SIGHUP.'); + $logger->rotatelog(); + }; +} + +sub prestartup ($) { + my $conf = shift; + checkpid $conf; +} + +sub alive ($) { + my $conf = shift; +} + +sub daemonloop ($) { + my $conf = shift; + my $rmodule = RunModule->new($conf); + my $loopinterval = $conf->{'daemon.loopinterval'}; + + my $loop = shift; + for (my $i = 1;;++$i) { + $rmodule->do(); + sleep $loopinterval; + alive $conf; + } +} + +my $conf = readconf shift; +$conf->{logger} = Logger->new($conf); + +prestartup $conf; +daemonize $conf; +sighandlers $conf; +daemonloop $conf; + + diff --git a/lib/RunModule.pm b/lib/RunModule.pm new file mode 100644 index 0000000..a063faa --- /dev/null +++ b/lib/RunModule.pm @@ -0,0 +1,17 @@ +package RunModule; + +sub new ($$$) { + my ($class, $conf) = @_; + + return bless { conf => $conf }, $class; +} + +sub do ($) { + my $self = shift; + my $conf = $self->{conf}; + my $logger = $conf->{logger}; + + $logger->logmsg('Test'); +} + +1; |
