]>
Commit | Line | Data |
---|---|---|
e2a9c450 SS |
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; |