File Coverage

blib/lib/System/Daemon.pm
Criterion Covered Total %
statement 71 90 78.8
branch 22 46 47.8
condition 4 11 36.3
subroutine 13 14 92.8
pod 6 7 85.7
total 116 168 69.0


line stmt bran cond sub pod time code
1             package System::Daemon;
2              
3 3     3   1422 use strict;
  3         3  
  3         111  
4 3     3   12 use warnings;
  3         3  
  3         81  
5              
6 3     3   30 use POSIX;
  3         3  
  3         24  
7 3     3   5928 use Carp;
  3         6  
  3         228  
8 3     3   12 use Fcntl ':flock';
  3         3  
  3         324  
9 3     3   1191 use System::Daemon::Utils;
  3         3  
  3         2031  
10              
11             our $VERSION = 0.13;
12             our $AUTHOR = 'justnoxx';
13             our $ABSTRACT = "Swiss-knife for daemonization";
14              
15             our $DEBUG = 0;
16              
17             our $LOCK;
18              
19             sub new {
20 3     3 1 201 my ($class, %params) = @_;
21              
22 3         6 my $self = {};
23 3         9 $self->{daemon_data}->{daemonize} = 1;
24              
25 3 50       9 if ($params{user}) {
26 0         0 $self->{daemon_data}->{user} = $params{user};
27             }
28              
29 3 50       6 if ($params{group}) {
30 0         0 $self->{daemon_data}->{group} = $params{group};
31             }
32            
33 3 50       9 if ($params{pidfile}) {
34 3         3 $self->{daemon_data}->{pidfile} = $params{pidfile};
35             }
36              
37 3 50       9 if ($params{mkdir}) {
38 0         0 $self->{daemon_data}->{mkdir} = 1;
39             }
40              
41 3 50       6 if ($params{procname}) {
42 0         0 $self->{daemon_data}->{procname} = $params{procname};
43             }
44            
45 3 50       6 if (exists $params{daemonize}) {
46 0         0 $self->{daemon_data}->{daemonize} = $params{daemonize};
47             }
48            
49 3 50       6 if ($params{cleanup_on_destroy}) {
50 0         0 $self->{daemon_data}->{cleanup_on_destroy} = 1;
51             }
52              
53 3         6 bless $self, $class;
54 3         9 return $self;
55             }
56              
57              
58             sub daemonize {
59 3     3 1 12 my $self = shift;
60              
61 3 50       21 unless ($self->{daemon_data}->{daemonize}) {
62 0         0 carp "Daemonization disabled";
63 0         0 return 1;
64             }
65            
66 3         3 my $dd = $self->{daemon_data};
67              
68 3         6 my $process_object = System::Daemon::Utils::process_object();
69              
70             # wrapper context
71 3         18882 System::Daemon::Utils::daemon();
72            
73             # let's validate user and group
74 1 50 33     30 if ($dd->{user} || $dd->{group}) {
75             System::Daemon::Utils::validate_user_and_group(
76             user => $dd->{user},
77             group => $dd->{group},
78 0 0       0 ) or do {
79 0         0 croak "Bad user or group";
80             };
81             }
82              
83 1 50       13 if ($dd->{pidfile}) {
84 1         41 System::Daemon::Utils::validate_pid_path($dd->{pidfile}, $dd->{mkdir});
85             }
86 1 50       21 System::Daemon::Utils::make_sandbox($dd) if $dd->{mkdir};
87             # daemon context
88 1 50       5 if ($dd->{pidfile}) {
89 1 50       21 croak "Can't overwrite pid file of my alive instance" unless $self->ok_pid();
90 1 50       5 if ($dd->{pidfile}) {
91 1         44 open $LOCK, $dd->{pidfile};
92 1         15 my $got_lock = flock($LOCK, LOCK_EX | LOCK_NB);
93 1 50       10 unless ($got_lock) {
94 0         0 warn "Can't get lock\n";
95 0         0 exit 1;
96             }
97             }
98              
99 1         14 System::Daemon::Utils::write_pid($dd->{pidfile}, undef,
100             user => $dd->{user},
101             group => $dd->{group}
102             );
103             }
104            
105 1 50 33     10 if ($dd->{user} || $dd->{group}) {
106 0         0 System::Daemon::Utils::apply_rights(
107             user => $dd->{user},
108             group => $dd->{group}
109             );
110             }
111              
112 1 50       2 if ($dd->{procname}) {
113 0         0 $0 = $dd->{procname};
114             }
115              
116 1 50       6 if ($dd->{cleanup_on_destroy}) {
117             *{System::Daemon::DESTROY} = sub {
118 0     0   0 my $obj = shift;
119 0         0 $obj->cleanup();
120 0         0 };
121             }
122              
123 1         3 System::Daemon::Utils::suppress();
124 1         20 return 1;
125             }
126              
127              
128             sub exit {
129 1     1 1 391 my ($self, $code) = @_;
130              
131 1         4 $self->finish();
132              
133 1   50     18 $code ||= 0;
134 1         12 exit $code;
135             }
136              
137              
138             sub ok_pid {
139 1     1 0 3 my ($self, $pidfile) = @_;
140              
141 1   33     15 $pidfile ||= $self->{daemon_data}->{pidfile};
142              
143 1 50       3 return 1 unless $pidfile;
144              
145 1 50       22 unless (System::Daemon::Utils::pid_init($self->{daemon_data}->{pidfile})) {
146 0         0 croak "Can't init pidfile";
147             }
148              
149 1         1 my $pid;
150 1 50       5 unless ($pid = System::Daemon::Utils::read_pid($pidfile)) {
151 1         5 return 1;
152             }
153              
154 0         0 return 1;
155             }
156              
157              
158             sub cleanup {
159 1     1 1 328 my ($self) = @_;
160              
161 1         5 return $self->finish();
162             }
163              
164              
165             sub finish {
166 2     2 1 5 my ($self) = @_;
167              
168 2         3 my $dd = $self->{daemon_data};
169              
170 2 50       8 if ($dd->{pidfile}) {
171 2         7 System::Daemon::Utils::delete_pidfile($dd->{pidfile});
172             }
173             }
174              
175              
176             sub process_object {
177 1     1 1 28 my ($self) = @_;
178              
179 1         6 return System::Daemon::Utils::process_object();
180             }
181              
182             1;
183              
184             __END__