I can duplicate your problem. I modified your code like this
for testing:
use strict;
use File::Copy;
use Fcntl ':flock'; # import LOCK_* constants
my $status_file = "/tmp/flocktest";
open(STATUS, "+<$status_file") || die "Can't open file";
print "getting lock...\n";
flock(STATUS,LOCK_EX) || die "Can't lock file";
print "waiting...\n";
sleep 10;
print "copying file...\n";
# copy(\*STATUS,"/tmp/foo");
copy("$status_file","/tmp/foo");
print "finished copy, waiting....\n";
sleep 10;
With the \*STATUS line uncommented, I get the following behavior
(the two columns represent two terminals):
% ./test.pl
getting lock...
waiting...
% ./test.pl
getting lock...
copying file...
finished copy, waiting...
%
waiting...
copying file...
finished copy, waiting...
%
And with the "$status_file" line uncommented, I get:
% ./test.pl
getting lock...
waiting...
% ./test.pl
getting lock...
copying file...
finished copy, waiting...
waiting...
copying file...
finished copy, waiting...
% %
The only explanation I can offer comes from the flock(3B) man
page in Solaris:
Locks are on files, not file descriptors. That is, file
descriptors duplicated through dup(2) or fork(2) do not
result in multiple instances of a lock, but rather multiple
references to a single lock. If a process holding a lock on
a file forks and the child explicitly unlocks the file, the
parent will lose its lock. Locks are not inherited by a
child process.
This tells me that when copy() closes the file (even if it
opened it using a different handle) the lock is lost. I may
be completely wrong, though...
--ZZamboni
|