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};
}