summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2011-05-13 14:04:27 +0000
committerPaul Buetow <paul@buetow.org>2011-05-13 14:04:27 +0000
commit73af1eb840720cf21c420c9a38021f6aa2f41b8f (patch)
treee73577e5b615837355d7171a1e1e8942f5c40824
parentd4f295dd34384b71acc6c8c12076719f9bc97c0f (diff)
copied stuff into ./lib
-rw-r--r--lib/Logger.pm40
-rw-r--r--lib/PerlDaemon.pl164
-rw-r--r--lib/RunModule.pm17
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;