Question

i use Perl v5.10.1, and have next part of code:

#!/usr/bin/perl
use Fcntl qw(LOCK_EX LOCK_NB);
my ( $fh, $path );
$path = q{/var/run/}. time() .q{.pid};
sysopen $fh, $path, O_RDWR|O_CREAT || die qq{Cannot open "$path": $!\n};
flock ( $fh, LOCK_EX | LOCK_NB) || die qq{pid "$path" already locked: $!\n};

when i try to run it:

pid "/var/run/1392394505.pid" already locked: Bad file descriptor

What's wrong with it? Any ideas?

Was it helpful?

Solution

That means $fh doesn't contain a file handle. That's because you incorrectly checked if sysopen succeeded. Specifically, you are suffering from a precedence issue.

sysopen $fh, $path, O_RDWR|O_CREAT || die qq{Cannot open "$path": $!\n};

means

sysopen $fh, $path, ( O_RDWR|O_CREAT || die qq{Cannot open "$path": $!\n} );

which means

sysopen $fh, $path, O_RDWR|O_CREAT;

Use or instead of ||. You could also use parens. Or both. Fixed:

sysopen(my $fh, $path, O_RDWR|O_CREAT)
   or die qq{Can't open "$path": $!\n};

Two other errors: 1) You never import O_RDWR and O_CREAT, so you're actually passing a junk string for sysopen's third argument. (Always use use strict; use warnings;!) 2) Your error message is incorrect. You say it's already locked even when it isn't. Fixed:

#!/usr/bin/perl
use strict;
use warnings;
use Fcntl qw( LOCK_EX LOCK_NB O_RDWR O_CREAT );
my $path = q{/var/run/}. time() .q{.pid};
sysopen(my $fh, $path, O_RDWR|O_CREAT)
   or die qq{Cannot open "$path": $!\n};
if (!flock($fh, LOCK_EX | LOCK_NB)) {
   die qq{Can't lock "$path": $!\n} if !$!{EWOULDBLOCK};
   die qq{pid already locked\n};
}

OTHER TIPS

solved

there are no permissions to write in /var/run to this user.. sudo %scriptname% works ok

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top