Stanimirovv
Stanimirovv

Reputation: 3172

Do file locks stay when you use open for a second time?

Suppose:

my $fh;
open $fh, ">>", "file.txt";
flock($fh, LOCK_EX);
open $fh, "+<", "file.txt";
close $fh;

Will the file lock stay or will it be released? If it will be released is there a way to make it stay ? I cloud not find relevant information.

Upvotes: 3

Views: 122

Answers (3)

mob
mob

Reputation: 118605

Calling open on a filehandle that is already assigned to an open file descriptor performs an implicit close on the filehandle. And closing a locked filehandle releases the lock.

It's not clear to me what you are trying to do by opening the same file with the same filehandle in two different modes. What if you used a second filehandle?

open my $fh, ">>", "file.txt";
flock($fh, LOCK_EX);
open my $fh2, "+<", "file.txt";
... rewrite 'file.txt' with $fh2 ...
close $fh2;   # done with rewrite
close $fh;    # done with lock

It looks like flock is respected for a file in +< mode (works in Linux, this might not be portable), so with that and some seek statements, you only need a single filehandle.

# make sure file exists before you use '+<' mode
{ open my $touch,'>>','file.txt'; }

open my $fh, '+<', 'file.txt';
flock $fh, LOCK_EX;

seek $fh, 0, 2;
print $fh 'stuff for the end of the file';

seek $fh, 0, 0;
print $fh 'something for the start of the file';

close $fh;  # releases lock

Upvotes: 3

ikegami
ikegami

Reputation: 385897

I wouldn't rely on it on whatever behaviour you observe.


I think you're trying to open a file handle for read-writing, creating it if necessary, but without clobbering any existing content, and that you've discovered that open can't do all three.

Instead of two uses of open, use the following:

use Fcntl qw( O_RDWR O_CREAT LOCK_EX );

sysopen(my $fh, "file.txt", O_RDWR | O_CREAT, 0666)
   or die($!);
flock($fh, LOCK_EX)
   or die($!);

Using File::Temp could make your life easier.

Upvotes: 1

Borodin
Borodin

Reputation: 126722

No, you will lose the lock because the second open call on the same file handle implicitly closes the original one first.

What are you trying to do? It looks as though you want to keep the file entirely to yourself, in which case I recommend creating a temporary file with File::Temp and locking that as a flag. Then other processes will request the lock that they want on the same temporary file, and can then go ahead and work on file.txt when they get it.

Do you realise that flock is cooperative, so it won't stop another process from doing what it likes with the file unless it is also using flock and waiting for the access to be granted?

Upvotes: 3

Related Questions