Add "Daemon" module.
authorStefan Schantl <stefan.schantl@ipfire.org>
Wed, 9 Dec 2015 13:43:36 +0000 (14:43 +0100)
committerStefan Schantl <stefan.schantl@ipfire.org>
Wed, 9 Dec 2015 13:43:36 +0000 (14:43 +0100)
This module contains various functions which can be used to Daemonize (forking guardian into background), writing PID (process-id) files and to determine if an instance of guardian is already running.

Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
modules/Daemon.pm [new file with mode: 0644]

diff --git a/modules/Daemon.pm b/modules/Daemon.pm
new file mode 100644 (file)
index 0000000..221e2b6
--- /dev/null
@@ -0,0 +1,151 @@
+package Guardian::Daemon;
+use strict;
+use warnings;
+use POSIX;
+
+use Exporter qw(import);
+
+our @EXPORT_OK = qw(Daemonize IsRunning GetPID WritePID RemovePIDFile);
+
+# The file and path where the pidfile which contains the PID (process id)
+# of guardian when running in daemon mode will be written.
+my $pidfile = "/run/guardian/guardian.pid";
+my $pid_path = "/run/guardian";
+
+#
+## The main function to daemonize guardian.
+#
+## When this function is called, the running guardian process will be forked
+## into the background and become a daemon.
+#
+sub Daemonize {
+       # Setting the session identifier to the current process.
+       &POSIX::setsid or die "Could not set session identifer (setsid): $!";
+
+       # Fork into the background.
+       my $pid = fork ();
+
+       # Check if we forked successfully.
+       if ($pid < 0) {
+               die "Could not fork into background: $!";
+
+       # Clean exit the parent process.
+       } elsif ($pid) {
+               exit 0;
+       }
+
+       # Change working directory.
+       chdir "/";
+
+       # Set file umask.
+       umask 022;
+
+       # Set max number of "open" descriptors to system default, if not set
+       # use 1024.
+       foreach (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024))
+
+       # This function does not require any input, so close it.
+       { POSIX::close $_ }
+
+       # Open new I/O streams.
+       open (STDIN, "</dev/null");
+       open (STDOUT, ">/dev/null");
+       open (STDERR, ">&STDOUT");
+
+       # Call sub to write out the process id.
+       &WritePID();
+}
+
+#
+## Function WritePID.
+#
+## This function will write the current process id to guardians PID file. If the path to
+## does not exist yet, it automatically will be created.
+#
+sub WritePID () {
+       # Create directory for storing the pidfile if it does not exist yet.
+       unless (-d "$pid_path") {
+               mkdir($pid_path);
+       }
+       
+       # Create pidfile.
+       open(PIDFILE, ">$pidfile") or die "Could not write $pidfile. $!\n";
+
+       # Write process-id to the pidfile.
+       print PIDFILE "$$";
+
+       # Close pidfile.
+       close(PIDFILE);
+}
+
+#
+## Function GetPID.
+#
+## This subfunction provides an easy to use mechanism to the the process id (PID)
+## from the pidfile of guardian.
+#
+sub GetPID () {
+       # Check if the pidfile exists.
+       unless (-r "$pidfile") {
+               return undef;
+       }
+
+       # Open the pidfile.
+       open(PIDFILE, "<$pidfile") or die "Could not open $pidfile: $!\n";
+
+       # Read the process id.
+       my $pid = <PIDFILE>;
+
+       # Close the file afterwards.
+       close(PIDFILE);
+
+       # Check if we got a valid process id.
+       unless ($pid =~ /^(\d+)$/ ) {
+               return undef;
+       }
+
+       # Return the process id.
+       return $pid;
+}
+
+#
+## Function IsRunning.
+#
+## A subfunction to check if a process by a given process id (PID) is running or not.
+#
+sub IsRunning () {
+       # Grab process id
+       my $pid = &GetPID();
+
+       # If we got no process id, no instance of guardian is running yet.
+       unless ($pid) {
+               return undef;
+       }
+
+       # Check if the process exists or not by sending a test signal to the process id.
+       my $is_running = kill(0, $pid);
+
+       # Return true if the process is running.
+       if ($is_running) {
+               return "True";
+       }
+
+       # If we got here, there is not process running which uses the given id or something
+       # went wrong. Return undef (False) in this case.
+       return undef;
+}
+
+#
+## RemovePIDFile function.
+#
+## This very tiny function just removes an existing PID file.
+#
+sub RemovePIDFile () {
+       # Check if a socketfile exists.
+       if (-e $pidfile) {
+               # Delete the pid file.
+               unlink($pidfile);
+       }
+}
+
+1;