Using flock for in place edting presents no special problems beyond the usual reading and writing. Since you are writing, you will want to use the LOCK_EX flag, an exclusive lock.
| [reply] [Watch: Dir/Any] |
Seems to me there's a race condition, since perl will open/rename/read all within the <> operator. You may want to not use the built-in inplace edit but code your own.
| [reply] [Watch: Dir/Any] |
Thanks to Mark for the quick reply.
Would you then flock the file like this?
use Fcntl ':flock';
@ARGV = "file.tab";
$^I = ".bak";
flock(ARGV,LOCK_EX);
seek(ARGV, 0, 2);
while (<>) {
s/foo/bar/;
print;
}
flock(ARGV,LOCK_UN);
Does anybody know if this is right, or even the way to lock whilst using inplace editing?
Regards,
Phil
| [reply] [Watch: Dir/Any] [d/l] |
Always error check your syscalls. It's easy to do. If you had written this:
flock(ARGV,LOCK_EX) or die "flock failed: $!";
You would have seen an error message like this:
flock failed: Bad file descriptor at foo line 6.
The problem is that the ARGV filehandle isn't open util you hit the while (<>) { line, so you can't lock it. After that, it's too late to lock. Follow one of the other suggestions, and either lock a separate lockfile, or write your own in-place edit code. The built-in $^I is nice for a quick script, but it's not always the best way to go. | [reply] [Watch: Dir/Any] [d/l] [select] |
Great! Which filehandle do I lock?
| [reply] [Watch: Dir/Any] |
When I had the question of "which filehandle to flock", because I was reading a file, then writing the file, requiring me to close, then reopen it (in retrospect, I probably should have just used seek or some such), the solution was to flock a wholly separate file instead, eg.
open LCK, "$file.lck";
flock(LCK, LOCK_EX);
# operate on how ever many files here
flock(LCK, LOCK_UN);
close LCK;
Of course, this only protects you from other instances of the same program, or other programs that use the same mechanism.
--Bob Niederman, http://bob-n.com All code given here is UNTESTED unless otherwise stated.
| [reply] [Watch: Dir/Any] [d/l] |