From e2a9c45020334210348427e4073035c8bd747cd6 Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Wed, 9 Dec 2015 14:43:36 +0100 Subject: [PATCH] Add "Daemon" module. 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 --- modules/Daemon.pm | 151 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 modules/Daemon.pm diff --git a/modules/Daemon.pm b/modules/Daemon.pm new file mode 100644 index 0000000..221e2b6 --- /dev/null +++ b/modules/Daemon.pm @@ -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 (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 = ; + + # 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; -- 2.39.2