diff options
| author | Paul Buetow <paul@buetow.org> | 2011-05-13 14:04:27 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2011-05-13 14:04:27 +0000 |
| commit | 73af1eb840720cf21c420c9a38021f6aa2f41b8f (patch) | |
| tree | e73577e5b615837355d7171a1e1e8942f5c40824 | |
| parent | d4f295dd34384b71acc6c8c12076719f9bc97c0f (diff) | |
copied stuff into ./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..fccc274 --- /dev/null +++ b/lib/Logger.pm @@ -0,0 +1,40 @@ +package PerlDaemon::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..240134d --- /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 PerlDaemon::Logger; +use PerlDaemon::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'} if -f $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 = PerlDaemon::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} = PerlDaemon::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..4f2c492 --- /dev/null +++ b/lib/RunModule.pm @@ -0,0 +1,17 @@ +package PerlDaemon::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; |
