Ian the Terrible has asked for the wisdom of the Perl Monks concerning the following question:

I've got a script that needs to: The file gets written/appended to by a different process, at unpredictable intervals, so I lock the file while I'm parsing it. Here's some code:
open (FILE, $my_file); flock FILE, 2; #exclusive lock #Parse file and do various things with the content. flock FILE, 8; # unlock close ( FILE ); unlink $my_file;
There are plenty of "or die" and "or warn" clauses in the real code, so I'll know if something fails. What bothers me is that closing sequence. It's possible that $my_file could get written to after it gets unlocked, and then vanish when it gets unlinked. Is there a better way to handle this kind of thing?

Replies are listed 'Best First'.
Re: Avoiding a race condition
by c-era (Curate) on May 19, 2000 at 04:16 UTC
    I don't have time to test this, but you should be able to unlink the file before you close it. Unix will mark a file to be deleted, but it won't actually delete the file until the file is closed.

    You can also open the file in read/write mode. Read from the file then truncate the file to nothing and close it.

    open (FILE,"+</path/file"); flock (FILE,2); # Do something with the data seek (FILE,0,0); truncate (FILE,tell (FILE)); close FILE; #file unlocks when closed
      This is correct. In fact, it is a very common practice for temporary files to unlink them right after opening them. Only the processes that already had them open will be able to continue accessing them, and the file will magically vanish when the last process closes it.

      From the unlink(2) man page under Linux:

      If the name was the last link to a file but any processes still have the file open the file will remain in existence until the last file descriptor referring to it is closed.

      --ZZamboni

        This is a common practice for unix. Not all platforms allow you to unlink an open file.
Re: Avoiding a race condition
by takshaka (Friar) on May 19, 2000 at 06:32 UTC
    There's no need to unlock the file before closing. On older versions of Perl, this can result in data loss because unlocking can happen while there are unflushed buffers. Newer Perls do a flush before unlocking.

    Just truncate the file to zero and close.

    For finer-grained control, look at a combination of sysopen with the O_EXCL flag and flock. See perldoc perlopentut (which doesn't seem to be in the Library).

Re: Avoiding a race condition
by Ian the Terrible (Beadle) on May 19, 2000 at 11:37 UTC
    Oop. Wasn't logged in. Thanks again.
Re: Avoiding a race condition
by Anonymous Monk on May 19, 2000 at 11:28 UTC
    Thanks, all. The system in question is running Linux, so unlinking before unlocking will solve my problem.