geohar has asked for the wisdom of the Perl Monks concerning the following question:
But.... I can't find a reliable method to rename a file that works without releasing the lock first. The standard rename doesn't work, neither does File::Copy's move. Both barf if the file you want to write over is locked. Is there any way to do this or am I forced to open both files read-write (sysopen style), perform the filter, then seek both to the start and copy in reverse. Is that the only way? Help much appreciated.use Fctl qw(:flock); my $fh = new IO::File("file1","r"); flock($fh,LOCK_EX) or die "can't get lock"; my $fh2 = new IO::File("file2","w"); # read fh and write fh2 (ie do a filter) # move fh2 over fh # rename("file2","file1"); doesn't work # File::Copy's move($fh2,$fh1); doens't work flock($fh,LOCK_UN);
or whether the renaming of file2 over file1, whilst we have file1 open is only valid on a unix-style system, or is it guaranteed to work, provided we have a valid flock etc.#!/usr/bin/perl use IO::File; use Fcntl qw(:DEFAULT :flock); print "opening file1\n"; my $fh1 = new IO::File("file1",O_RDONLY | O_CREAT); print "locking file1\n"; flock($fh1,LOCK_EX) or die "failed to lock file1"; print "opening file2\n"; my $fh2 = new IO::File("file2",O_WRONLY | O_CREAT); print "writing to file2\n"; print $fh2 "file2"; close($fh2); print "renaming file2 over file1\n"; rename("file2","file1") or die "failed to rename file2 over file1"; print "unlocking file1\n"; #flock($fh1,LOCK_UN);#probably not needed as close does it #(might cause issues with buffering?) close($fh1);
#!/usr/bin/perl use IO::File; use File::Copy; use Fcntl qw(:DEFAULT :flock); print "opening and locking file~\n"; my $fh_lock = new IO::File("file~",O_RDWR | O_CREAT); flock($fh_lock,LOCK_EX) or die "failed to lock file1"; print "opening file1\n"; my $fh1 = new IO::File("file1",O_RDWR | O_CREAT); print "opening file2\n"; my $fh2 = new IO::File("file2",O_WRONLY | O_CREAT); print "reading from file1\n"; seek($fh1,0,2); close($fh1); print "writing to file2\n"; print $fh2 "file2"; close($fh2); print "renaming file2 over file1\n"; rename("file2","file1") or print "failed to rename file2 over file1, $!\n"; print "unlocking file~\n"; #flock($fh_lock,LOCK_UN); #bad with older flock implementations close($fh_lock); unlink("file~") or print "couldn't remove lock - someone else must have it";
|
|---|