File Coverage

blib/lib/CTK/FilePid.pm
Criterion Covered Total %
statement 72 73 98.6
branch 23 32 71.8
condition 6 10 60.0
subroutine 16 16 100.0
pod 6 6 100.0
total 123 137 89.7


line stmt bran cond sub pod time code
1             package CTK::FilePid;
2 2     2   1148 use strict;
  2         4  
  2         50  
3 2     2   982 use utf8;
  2         24  
  2         8  
4              
5             =encoding utf-8
6              
7             =head1 NAME
8              
9             CTK::FilePid - The Pid File simple interface
10              
11             =head1 VERSION
12              
13             Version 1.05
14              
15             =head1 SYNOPSIS
16              
17             use CTK::FilePid;
18              
19             my $pidfile = CTK::FilePid->new ({
20             file => '/some/file.pid',
21             });
22              
23             if ( my $num = $pidfile->running ) {
24             die "Already running: $num";
25             } else {
26             $pidfile->write;
27              
28             # ...
29              
30             $pidfile->remove;
31             }
32              
33             ... or with autoremove:
34              
35             my $pidfile = CTK::FilePid->new ({
36             file => '/some/file.pid',
37             autoremove => 1,
38             });
39              
40             if ( my $num = $pidfile->running ) {
41             die "Already running: $num";
42             } else {
43             $pidfile->write;
44              
45             # ...
46             }
47              
48             =head1 DESCRIPTION
49              
50             This software manages a pid file for you. It will create a pid file,
51             query the process within to discover if it's still running, and remove
52             the pid file.
53              
54             This module is based on L module
55              
56             =head2 new
57              
58             my $pidfile = CTK::FilePid->new;
59              
60             my $thisfile = File::Pid->new({
61             file => '/var/run/daemon.pid',
62             });
63              
64             my $thisfileandpid = CTK::FilePid->new({
65             file => '/var/run/daemon.pid',
66             pid => '145',
67             autoremove => 1,
68             });
69              
70             This constructor takes three optional paramters.
71              
72             C - The name of the pid file to work on. If not specified, a pid
73             file located in C. So, for example, if C<$0> is F<~/bin/sig.pl>,
74             the pid file will be F.
75              
76             C - The pid to write to a new pidfile. If not specified, C<$$> is
77             used when the pid file doesn't exist. When the pid file does exist, the
78             pid inside it is used.
79              
80             C - Auto-remove flag. If this flag specified as true, then
81             will be removed the pid file automatically on DESTROY phase. Default: false
82              
83             =head2 file
84              
85             $pidfile->file("/var/run/file.pid");
86             my $pidfile = $pidfile->file;
87              
88             Accessor/mutator for the filename used as the pid file.
89              
90             =head2 pid
91              
92             $pidfile->pid(123);
93             my $pid = $pidfile->pid;
94              
95             Accessor/mutator for the pid being saved to the pid file.
96              
97             =head2 remove
98              
99             $pidfile->remove or warn "Couldn't unlink pid file";
100              
101             Removes the pid file from disk. Returns true on success, false on
102             failure.
103              
104             =head2 running
105              
106             my $pid = $pidfile->running;
107             die "Service already running: $pid" if $pid;
108              
109             Checks to see if the pricess identified in the pid file is still
110             running. If the process is still running, the pid is returned. Otherwise
111             C is returned.
112              
113             =head2 write
114              
115             my $pid = $pidfile->write;
116              
117             Writes the pid file to disk, inserting the pid inside the file.
118             On success, the pid written is returned. On failure, C is
119             returned.
120              
121             =head1 HISTORY
122              
123             See C file
124              
125             =head1 TO DO
126              
127             See C file
128              
129             =head1 BUGS
130              
131             * none noted
132              
133             =head1 SEE ALSO
134              
135             L
136              
137             =head1 AUTHOR
138              
139             Serż Minus (Sergey Lepenkov) L Eabalama@cpan.orgE
140              
141             =head1 COPYRIGHT
142              
143             Copyright (C) 1998-2022 D&D Corporation. All Rights Reserved
144              
145             =head1 LICENSE
146              
147             This program is free software; you can redistribute it and/or
148             modify it under the same terms as Perl itself.
149              
150             See C file and L
151              
152             =cut
153              
154 2     2   96 use vars qw/$VERSION/;
  2         4  
  2         84  
155             $VERSION = 1.05;
156              
157 2     2   10 use File::Spec;
  2         2  
  2         40  
158 2     2   6 use File::Basename qw/basename/;
  2         4  
  2         86  
159 2     2   976 use CTK::Util qw/fload fsave rundir/;
  2         4  
  2         1170  
160              
161             sub new {
162 6     6 1 647645 my $class = shift;
163 6         25 my $tst = $_[0];
164 6         12 my %args = ();
165 6 50 33     124 if (defined($tst) && ref($tst) eq 'HASH') {
166 0         0 %args = %$tst;
167             } else {
168 6         80 %args = @_;
169             }
170 6   100     79 $args{autoremove} ||= 0;
171              
172 6         59 my $self = bless {%args}, $class;
173 6         56 $self->_get_pidfile;
174 6         16 $self->_get_pid;
175 6         28 $self->{owner} = 0;
176 6         14 $self->{is_running} = -1; # Unknown (is as running)
177              
178 6         74 return $self;
179             }
180              
181             sub file {
182 54     54 1 69 my $self = shift;
183 54 50       110 $self->{file} = shift if scalar(@_) >= 1;
184 54         163 return $self->{file};
185             }
186             sub pid {
187 35     35 1 59 my $self = shift;
188 35 100       96 $self->{pid} = shift if scalar(@_) >= 1;
189 35         139 return $self->{pid};
190             }
191             sub running {
192 5     5 1 13 my $self = shift;
193 5   50     11 my $pid = $self->_get_pid_from_file || 0;
194 5 100       66 my $r = kill(0, $pid) ? $pid : undef;
195 5 100       14 $self->{is_running} = $r ? 1 : 0;
196 5         30 return $r;
197             }
198             sub remove {
199 5     5 1 10 my $self = shift;
200 5         9 $self->{owner} = 0;
201 5         8 my $file = $self->_get_pidfile;
202 5 50       67 return unless -e $file;
203 5         275 unlink $file;
204             }
205             sub write {
206 5     5 1 16 my $self = shift;
207 5         9 my $file = $self->_get_pidfile;
208 5         10 my $pid = $self->_get_pid;
209 5 50       64 fsave($file, "$pid\n" ) or return;
210 5         17 $self->{owner} = $pid;
211 5         23 return $pid;
212             }
213              
214             sub _get_pidfile {
215 27     27   33 my $self = shift;
216 27 50       65 $self->file(File::Spec->catfile(rundir(), sprintf("%s.pid", basename($0)))) unless $self->file;
217 27         54 return $self->file;
218             }
219             sub _get_pid {
220 13     13   15 my $self = shift;
221 13 100 66     43 $self->pid($self->_get_pid_from_file || $$) unless $self->pid;
222 13         25 return $self->pid;
223             }
224             sub _get_pid_from_file {
225 11     11   17 my $self = shift;
226 11         31 my $file = $self->_get_pidfile;
227 11 100       296 return unless -e $file;
228 6         38 my $pid = fload($file);
229 6 50       21 return unless $pid;
230 6         29 chomp $pid;
231 6         23 return $pid;
232             }
233              
234             sub DESTROY {
235 6     6   1786 my $self = shift;
236 6 50       15 return unless $self;
237 6 100       66 return unless $self->{autoremove};
238 3 100       26 return $self->remove unless $self->{is_running};
239 2 50       6 return unless $self->{owner};
240 2 50       4 return unless $self->{owner} == $self->_get_pid;
241 2         4 $self->remove;
242             }
243              
244             1;
245              
246             __END__