in reply to Writing to flock files in a daemon

Why is the PID not being written to the file until after the script is HUPped?

I'm guessing that you have a buffering problem. There can be a substantial delay between when the script "writes" into the file, and the next event that can cause I/O buffers to be flushed. Consult your favorite reference for instructions on unbuffering (hint: it'll invole the single argument form of select() ).

You're also openning the lock file in "append" mode. Better to just truncate and rewrite.

Replies are listed 'Best First'.
Re: Re: Writing to flock files in a daemon
by graq (Curate) on Mar 07, 2002 at 16:11 UTC
    Thanks for the hint so far. I have modified the code, as you suggested. Changed the open to truncate instead of append, and tried using select.

    And yes, /tmp/_pid_file contains the PID.
    This is fine until I run the script a second time, when /tmp/_pid_file gets truncated even though startup fails.

    Any further suggestions?

    # As before .. # ... sub main { my $start_mess = "===== Starting $TASK"; $start_mess .= " (@_)" if @_; $start_mess .= " ====="; error( $start_mess ); my $FH; open( HIGHLANDER, ">$PID_FILE") or die( "Cannot write to $PID_FILE +: $!" ); { my $count = 0; { flock HIGHLANDER, LOCK_EX | LOCK_NB and last; sleep 1; redo if ++$count < 3; error( "Script is already running." ); die( "Startup failed, PID file locked." ); } } $FH = select(HIGHLANDER); $| = 1; select($FH); print HIGHLANDER $$; # .. # ..as before..

    <a href="http://www.graq.co.uk">Graq</a>

      Opening with ">" truncates the file. Since flock is and advisory lock (at least on Unix), it won't stop the second process from doing this. See open or "perldoc -f open".

      I tend to check for the file's existance first and then use "+<$file" if it's there and ">$file" if it's not. I think this is sloppy though since there is probably a race condition since the filecheck and the open occur at two different times (i.e. the file may come into existance between the file check and the open() call if another process was running at the same time). If the lock file is never really deleted after it is first, this probably isn't a problem.

      I'd suggest using sysopen with O_RDWR | O_CREAT and then truncating the file yourself just before you perform the write.

      bluto