in reply to Re: File lock question
in thread File lock question

Ok, now I see the reason.

... sub do_log { ... sysopen my $fh, $logfile, O_RDWR|O_CREAT or do {...}; my $tmp_file = "${logfile}_tmp"; if (flock $fh, LOCK_EX) { #exclusive lock open my $tmp_fh, '>', "$tmp_file" or do {...}; while (<$fh>) { .. my $line = $_; .. print $tmp_fh $line, "\n"; } close $tmp_fh or die "Can't close tmp_file: $!"; move($tmp_file, $logfile); } close $fh or die "Can't close logfile $!"; #unlocks automatic }

Replies are listed 'Best First'.
Re^3: File lock question
by mattk1 (Acolyte) on Nov 06, 2009 at 15:32 UTC
    A second question: I call a sub check_nr_of_lines($nr_ofl, $arch_path, $logfile, $fh); When the max nr of lines in the logfile is reached, I want to write the half nr of lines in an archive file and delete them in the logfile. The other half should still be in the logfile. The following code does not work. It creates only an empty archive file, and changes nothing in the logfile. What must I change?
    ... sub do_log { ... sysopen my $fh, $logfile, O_RDWR|O_CREAT or do {...}; my $tmp_file = "${logfile}_tmp"; if (flock $fh, LOCK_EX) { #exclusive lock open my $tmp_fh, '>', "$tmp_file" or do {...}; while (<$fh>) { .. $nr_ofl = $.; my $line = $_; .. print $tmp_fh $line, "\n"; } ... check_nr_of_lines($nr_ofl, $arch_path, $logfile, $fh); ... close $tmp_fh or die "Can't close tmp_file: $!"; move($tmp_file, $logfile); } close $fh or die "Can't close logfile $!"; #unlocks automatic } sub check_nr_of_lines { my ($nr_of_lines, $arch_path, $logfile, $fh) = @_; if ( $nr_of_lines >= max_nr_of_lines_per_logfile ) { eval { mkpath($arch_path) }; if ($@) { ... } my $c = int($nr_of_lines / 2); open my $fh3, '>', "$arch_path/arch_test.log" or do { ... }; seek($fh, 0, 0); while (<$fh>) { print; if ($. <= $c) { print $fh3 $_; last; } print $fh $_; } } return; }
      In do_log you are calling a subroutine called move, what does that do? Did you mean rename perhaps? It's an easy mistake to make - the UNIX program mv(1) calls the kernel API rename(2), which is also called by Perl (on Windows the command-line program is called rename but the API is called MoveFile!). However, I would have thought that you would have at least got a warning for that.

      In check_nr_of_line you are using $fh, which is a bit suspicious since you close $fh in do_log. Check the return code from the seek?