Subject: | Pid in object is not reset when remove() is called |
When a pidfile is removed, e.g. when discovering that the pid contained
in it does not correspond to a running process, the 'pid' field in the
object is not reset -- which means that a subsequent write() operation
will write the old pid, rather than $$.
Here is a testcase which demonstrates the issue (and would test the fix):
# Tests the bug where removing a pidfile does not wipe the
remembered pid,
# meaning when the file is written back out again it writes the old
pid rather
# than reverting to $$, which is usually what the caller application
wants:
# This is a fairly typical usecase:
# if (not $pidfile->running)
# {
# $pidfile->remove;
# }
# else
# {
# exit -1;
# }
#
# $pidfile->write;
use strict;
use warnings;
use File::Pid;
use File::Temp;
use Test::More tests => 1;
my $filename = File::Temp->new->filename;
# write a bogus pid into the file
my $pidfile = File::Pid->new({file => $filename});
$pidfile->pid(70000);
$pidfile->write;
undef $pidfile;
# create a new object, read in this bogus pid
$pidfile = File::Pid->new({file => $filename});
# this process is obviously not running, so we will
# want to remove the file before writing our new pid
$pidfile->remove;
$pidfile->write;
# now verify that the pid we wrote really is the right one
is($pidfile->pid, $$, 'we wrote the correct pid, not our old bogus
one');
# clean up
$pidfile->remove;
To fix, simply apply this patch:
--- Pid.pm 2010-06-29 23:54:45.000000000 +0000
+++ Pid_fixed.pm 2010-06-29 23:55:59.000000000 +0000
@@ -135,7 +135,12 @@
=cut
-sub remove { unlink shift->_get_pidfile }
+sub remove
+{
+ my $self = shift;
+ $self->pid(0);
+ unlink $self->_get_pidfile;
+}