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

I have a question regarding whether a file is currently opened or not (unix). I've written a perl utility which does a directory comparison and picks out any new files that have appeared since it's previous run. I need to check the contents of these new files but only if they are not currently still open by some other process. These files are being written by an Oracle application not by another Perl utility.
I tried using flock but this doesn't seem to work e.g.
while (defined($_ = readdir(AUDDIR))) { next if /^\.\.?$/; unless (delete $files{$_}) { open(FH, "<$_") or die "Can't open file $_: $!\n"; flock(FH, LOCK_EX) or warn "Can't get exclusive lock on file $_ +: $!\n"; close(FH); } }
Notice that in this code I am using exclusive lock mode (even though all I want to do is read the contents). If I use LOCK_SH it grants a shared lock even if the file is currently openned by another process. Using LOCK_EX I get an error
Can't get exclusive lock on file ora_6688.aud : Bad file number
This happens regardless of whether the file is still openned or not.
As it happens in this case the filenames contain the unix pid of the process which wrote (or is still writing) to the file.
I could get a list of all the current pid's and compare it to the list of pid's in the new filenames to see if the filename in question is still open, but this seems a messy way of doing it to me.
Any suggestions on how I can handle this problem would be welcome

Replies are listed 'Best First'.
Re: Is file still open ?
by cdarke (Prior) on May 15, 2006 at 12:17 UTC
    Most UNIX file locking is discretionary, not mandatory, so you need co-operating processes for locking to achieve anything. Even if you get the lock, if the other process (Oracle) isn't using flock then it will have no effect.
    You may be able to get a spin-off from the /proc filesystem. Some UNIXs (inc. Linux) keep a record of open files for each process in there, but the format varies considerably.
Re: Is file still open ?
by Thelonius (Priest) on May 15, 2006 at 13:09 UTC
    Your LOCK_EX is probably failing because you only have the file opened for reading. Some operating systems require you to have the file open for writing to do LOCK_EX. But, as cdarke notes, locking won't tell you anything unless the other process is locking, too.

    Some versions of Unix (and Linux) support the fuser command. FreeBSD has the fstat command. On some versions of Unix, there's no way to tell!

    On most (I think all) Unixes, you can kill(pid, 0) to see if pid exists.

      It's important to stress that the fuser command, just like Linux::Fuser (worth pointing out, anyway!) just inspects the /proc filesystem to find out. I.e. there's not a "direct" record of the processes that are holding a certain file open. The relation that is actually remembered is the inverse one...

Re: Is file still open ?
by jonadab (Parson) on May 15, 2006 at 13:14 UTC
    ISTR that the Unix command lsof might have something to do with this. I'm not sure how consistent it is across various unices.
Re: Is file still open ?
by sgifford (Prior) on May 15, 2006 at 14:55 UTC
    As others have mentioned, there's unfortunately not a straightforward and portable way to find out if a file is still open. Here are some pragmatic possibilities (in other words, some hacks).
    • If you have control over the applications generating the data, you can modify them to use locking, and then use locking to find out if the files are still in use.
    • If you can't change the applications but do control how they're started, you could wrap them in a script that did some kind of locking, or have them write to a temporary file then move it into place when it's done.
    • If the applications write to the files fairly often as they're running, you can see if the file was modified recently, and if so assume that it might still be open and skip it; appropriate values of recently will vary by application.
Re: Is file still open ?
by Anonymous Monk on May 16, 2006 at 00:41 UTC

    Hi,

    I had a problem with all of the above solutions when
    receiving a file being sent from a VMS box to Solaris
    via ftp.

    At times the ftp process 'paused' for so long, everything
    thought it was finished, then it would start up again.

    In the end we got the VMS guys to send a 'DONE' file
    after the data file had been sent.

    This always worked for us, but...

Re: Is file still open ?
by TedPride (Priest) on May 15, 2006 at 19:22 UTC
    Read the new files, sleep 1 second, then compare file sizes. If the size of each file is still the same as it was when you read it, then the file isn't being written to and you're good to go.