Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Perl, how can I check if a file is locked?

Tags:

perl

How exactly would I check to see if a file is locked exclusively? I have this function but it is returning 1 no matter what I do:

sub is_file_locked
{
  my $theFile;
  my $theRC;

  ($theFile) = @_;
  $theRC = open(HANDLE, $theFile);
  $theRC = flock(HANDLE, LOCK_EX|LOCK_NB);
  close(HANDLE);
  return !$theRC;
}
like image 282
Christopher Peterson Avatar asked Dec 21 '10 18:12

Christopher Peterson


People also ask

How do I lock a file in Perl?

File locking can be done, in Perl, with the flock command. flock() accepts two parameters. The first one is the filehandle. The second argument indicates the locking operation required.

How do I know if a process is running in Perl?

Send a 0 (zero) signal to the process ID you want to check using the kill function. If the process exists, the function returns true, otherwise it returns false. Example: #-- check if process 1525 is running $exists = kill 0, 1525; print "Process is running\n" if ( $exists );


2 Answers

You have opened $theFile in read mode and LOCK_EX isn't meant to be used that way.

Note that the fcntl(2) emulation of flock(3) requires that FILEHANDLE be open with read intent to use LOCK_SH and requires that it be open with write intent to use LOCK_EX.

like image 140
mob Avatar answered Oct 29 '22 01:10

mob


First off, you should check if open succeeded.

Also, you should check if you can get a shared lock. flock with LOCK_EX would (I think) fail, if there is a shared lock on the file.

However, the file can become locked between the check and the return, creating a race condition, so such a function is of dubious value.

#!/usr/bin/perl

use strict; use warnings;
use Fcntl qw( :flock );

print is_locked_ex($0)
      ? "$0 : locked exclusively\n"
      : "$0 : not locked exclusively\n";

my $test_file = 'test.txt';
open my $fh, '>', $test_file
    or die "Cannot open '$test_file' for writing: $!";

if ( flock $fh, LOCK_EX|LOCK_NB ) {
    print is_locked_ex($test_file)
          ? "$test_file : locked exclusively\n"
          : "$test_file : not locked exclusively\n";
}

close $fh or die "Cannot close '$test_file': $!";

sub is_locked_ex {
    my ($path) = @_;

    die "Not a plain file: '$path'" unless -f $path;
    return 1 unless open my $fh, '<', $path;

    my $ret = not flock $fh, LOCK_SH | LOCK_NB;
    close $fh
        or die "Cannot close '$path': $!";

    return $ret;
}
like image 34
Sinan Ünür Avatar answered Oct 29 '22 01:10

Sinan Ünür