]> git.ipfire.org Git - people/stevee/guardian.git/blob - modules/Daemon.pm
Drop PID file when exiting guardian.
[people/stevee/guardian.git] / modules / Daemon.pm
1 package Guardian::Daemon;
2 use strict;
3 use warnings;
4 use POSIX;
5
6 use Exporter qw(import);
7
8 our @EXPORT_OK = qw(Daemonize IsRunning GetPID WritePID RemovePIDFile);
9
10 # The file and path where the pidfile which contains the PID (process id)
11 # of guardian when running in daemon mode will be written.
12 my $pidfile = "/run/guardian/guardian.pid";
13 my $pid_path = "/run/guardian";
14
15 #
16 ## The main function to daemonize guardian.
17 #
18 ## When this function is called, the running guardian process will be forked
19 ## into the background and become a daemon.
20 #
21 sub Daemonize {
22 # Setting the session identifier to the current process.
23 &POSIX::setsid or die "Could not set session identifer (setsid): $!";
24
25 # Fork into the background.
26 my $pid = fork ();
27
28 # Check if we forked successfully.
29 if ($pid < 0) {
30 die "Could not fork into background: $!";
31
32 # Clean exit the parent process.
33 } elsif ($pid) {
34 exit 0;
35 }
36
37 # Change working directory.
38 chdir "/";
39
40 # Set file umask.
41 umask 022;
42
43 # Set max number of "open" descriptors to system default, if not set
44 # use 1024.
45 foreach (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024))
46
47 # This function does not require any input, so close it.
48 { POSIX::close $_ }
49
50 # Open new I/O streams.
51 open (STDIN, "</dev/null");
52 open (STDOUT, ">/dev/null");
53 open (STDERR, ">&STDOUT");
54
55 # Call sub to write out the process id.
56 &WritePID();
57 }
58
59 #
60 ## Function WritePID.
61 #
62 ## This function will write the current process id to guardians PID file. If the path to
63 ## does not exist yet, it automatically will be created.
64 #
65 sub WritePID () {
66 # Create directory for storing the pidfile if it does not exist yet.
67 unless (-d "$pid_path") {
68 mkdir($pid_path);
69 }
70
71 # Create pidfile.
72 open(PIDFILE, ">$pidfile") or die "Could not write $pidfile. $!\n";
73
74 # Write process-id to the pidfile.
75 print PIDFILE "$$";
76
77 # Close pidfile.
78 close(PIDFILE);
79 }
80
81 #
82 ## Function GetPID.
83 #
84 ## This subfunction provides an easy to use mechanism to the the process id (PID)
85 ## from the pidfile of guardian.
86 #
87 sub GetPID () {
88 # Check if the pidfile exists.
89 unless (-r "$pidfile") {
90 return undef;
91 }
92
93 # Open the pidfile.
94 open(PIDFILE, "<$pidfile") or die "Could not open $pidfile: $!\n";
95
96 # Read the process id.
97 my $pid = <PIDFILE>;
98
99 # Close the file afterwards.
100 close(PIDFILE);
101
102 # Check if we got a valid process id.
103 unless ($pid =~ /^(\d+)$/ ) {
104 return undef;
105 }
106
107 # Return the process id.
108 return $pid;
109 }
110
111 #
112 ## Function IsRunning.
113 #
114 ## A subfunction to check if a process by a given process id (PID) is running or not.
115 #
116 sub IsRunning () {
117 # Grab process id
118 my $pid = &GetPID();
119
120 # If we got no process id, no instance of guardian is running yet.
121 unless ($pid) {
122 return undef;
123 }
124
125 # Check if the process exists or not by sending a test signal to the process id.
126 my $is_running = kill(0, $pid);
127
128 # Return true if the process is running.
129 if ($is_running) {
130 return "True";
131 }
132
133 # If we got here, there is not process running which uses the given id or something
134 # went wrong. Return undef (False) in this case.
135 return undef;
136 }
137
138 #
139 ## RemovePIDFile function.
140 #
141 ## This very tiny function just removes an existing PID file.
142 #
143 sub RemovePIDFile () {
144 # Check if a socketfile exists.
145 if (-e $pidfile) {
146 # Delete the pid file.
147 unlink($pidfile);
148 }
149 }
150
151 1;