Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I thank all of thoese who have helped me in the past. I love this site and I hope that I can "give back" as soon as I know alittle bit more about perl. Anyways I have a problem with perl. Here are a gist of my problem.
#start of login.cgi open(FILE, "file.log"); flock(FILE, LOCK_EX); print FILE "$a:$b:$c\n"; close FILE; #call function function; return 0; #end of login.cgi ------------------- ;#start of login.pl sub function { open(FILE, "file.log"); flock(FILE, LOCK_EX); $a = <FILE>; print "line: $a\n"; close FILE; #end of login.pl 1;
The first open, flock, print, and close work fine. Then when I call function, it is able to open the file, but the flock fails. If I don't flock the file, I'm able to read the first line from the file and print it. But I do need to lock the file. Am I correc to assume that the close in login.cgi will unlock the file? Can anyone help. Thanks, Michael

Replies are listed 'Best First'.
Re: flock problem
by jjhorner (Hermit) on Jul 14, 2000 at 21:09 UTC

    Not really related to the problem at hand, but try to find less obvious names for cgi programs. A lot of scanners do searches for common filenames with common extensions (login.pl, login.cfm, login.asp, login.cgi), so if you have a file named this, they will come back later and try to crack it.

    Avoid the temptation, don't throw them a bone.

    J. J. Horner
    Linux, Perl, Apache, Stronghold, Unix
    jhorner@knoxlug.org http://www.knoxlug.org/
    
Re: flock problem
by Ovid (Cardinal) on Jul 14, 2000 at 20:07 UTC
    First: what is the error message you are getting when the flock fails?

    Second: how are you defining LOCK_EX? Is it possible that you are defining that locally somewhere and its value is not being passed to the function?

    Third: Check all return calls!

    $filelog = "file.log"; open FILE, $filelog or die "Can't open $filelog: $!\n"; flock FILE, LOCK_EX or die "Can't write-lock $filelog: $!\n"; print FILE "$a:$b:$c\n" or die "Can't print to $filelog: $!\n"; close FILE or die "Can't print to $filelog: $!\n";
    The $! variable will have the error code that was generated by the failure. This may give you more information. However, if you don't have the or die construct in there, you may have a failure prior to your failure to flock the file.

    Also, notice that file.log is replaced by a variable rather than hardcoded. If you need to change this value in the future, you'll hate yourself for not doing this :)

    And yes, closing a file dissolves the flock.

    Cheers,
    Ovid

Re: flock problem
by c-era (Curate) on Jul 14, 2000 at 21:53 UTC
    You're going to kick yourself, you need to change "function;" to "function();"(We've all done this at one time or another).

    You also shouldn't use an exclusive lock when reading from a file, you should use a shared lock.
    This is how I got the code to work.

    #start of login.cgi open(FILE, ">file.log"); flock(FILE, 2); # 2 is an exclusive lock print FILE "$a:$b:$c\n"; close FILE; #call function function (); # return 0; #end of login.cgi ------------------- ;#start of login.pl sub function { open(FILE, "<file.log"); flock(FILE, 1); # 1 is a shared lock $a = <FILE>; print "line: $a\n"; close FILE; #end of login.pl 1; }
      The bareword function call may not be a problem, if login.pl has been required before the code we see. I always use the parenthesis on function calls, though, just to make things clear.

      I prefer to use the symbolic constants from Fcntl rather than the numbers, for the lock type argument to flock. It's just safer:

      use Fcntl qw(:DEFAULT :flock); # from the Perl Cookbook open(FILE, ">file.log") or die "Can't open and truncate file: $!"; flock(FILE, LOCK_EX) or die "Can't obtain exclusive lock: $!"; print FILE "$a:$b:$c\n"; close FILE;
      That'll clobber file.log, by the way. (if you don't want to do that, see mikfire's post here.)

      The code for login.pl is similar, except it's LOCK_SH there.

Re: flock problem
by mikfire (Deacon) on Jul 14, 2000 at 22:54 UTC
    Get thee to a tutorial and please, please, please stop using
    open FOO, ">file.txt";
    when you intend to lock the file. This has just destroyed the contents of the file, regardless of you getting the lock. Always open the file for append or read/write, never just for write.

    mikfire