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

I'm fairly new to perl so I'm sorry for the ignorance. I have written a script using flock that appends to a file. I believe that flock is working correctly, but my question is when I try to open the file should I still use die? So in other words, if the file is currently locked and someone else is trying to open it will it die or wait. Here is my code

open (UNSUB, ">>unsubscribe.txt") or die send_email("Open Unsubscribe. +txt$!\nUnsubscribe $surveyID"); flock (UNSUB, 2) or die send_email("Flock Unsubscribe.txt$!\nUnsubscri +be $surveyID"); print UNSUB "$surveyID\n"; close UNSUB;

Replies are listed 'Best First'.
Re: use die with flock
by Abigail-II (Bishop) on Jul 24, 2003 at 14:50 UTC
    Well, it's never necessary to use die after an open. You ought to check the return value of open, and do something appropriate if it fails. For many programs, a die is appropriate.

    Having said that, a flock is just a flock. Most systems don't have manditory locks, and a flock on a file does not prevent it to be opened. In fact, a flock on the file doesn't prevent it to be read, or written to. Multiple processes accessing a file do have to cooperate using flock, but if a process decides not to, you are out of luck.

    How systems work that have manditory file locking, with respect to open, I do not know.

    Abigail

      Abigail,
      I am not going to pretend to be authoratitive here, but I believe your very well written synopsis is true for *nix systems but not all operating systems. I believe file locking is more integrated into the OS for Win32 systems since you can't delete a locked file there where you can in *nix.

      Cheers - L~R

      Update: I didn't originally notice the word most which makes everything Abigail says valid. It is important to either write portable code that will behave correctly in all environments, or make the limitations of the code to a target platform well known.

Re: use die with flock
by cfreak (Chaplain) on Jul 24, 2003 at 15:03 UTC

    You should still check your open command for failure. It could fail for a number of reasons that have nothing to do with your flock call. That said, flock isn't going to die if a file is locked, rather it waits forever to get one and it dies if the platform doesn't support it, therefore IMHO checking the return status of flock is really not nessecary at all. Someone please correct me if I'm wrong.

    Lobster Aliens Are attacking the world!
      A flock can fail, even if the system supports and if you are not using LOCK_NB. See your systems manual page for lockf, flock and fcntl. (Perl can implement flock in different ways, depending on what the OS supports). One reason of failures is when you've reached the systems limit of locks.

      It's better to always check the return value of system calls. No harm is done if the system call cannot fail, but much harm could be done if you wrongly assumed it cannot fail, and it failed after all.

      The only time you don't need to check the return value of a system call is when you don't care if it fails. But then you should place a comment there, explaining why you aren't checking the return value of the system call.

      Abigail

Re: use die with flock
by edan (Curate) on Jul 24, 2003 at 15:20 UTC

    This is not answering your actual question, but something you might want to keep in mind:

    Since you open the file, then potentially wait on the flock, someone maybe have appended to the file in the meantime, so you should add the following line after the flock:

    seek(UNSUB, 0, 2);

    Or, if you want to make your code a little more understandable, you could do something like this UNTESTED example code:

    use Fcntl qw/:flock :seek/; open(UNSUB, ">>unsubscribe.txt"); flock(UNSUB, LOCK_EX); seek(UNSUB, 0, SEEK_END); print UNSUB "$surveyID\n"; close UNSUB;

    HTH

    Update: According to what Abigail-II just posted, it seems the seek is not necessary, at least on a Unix system, since 'the system (well, at least a Unix system) will seek to the end before you perform a write.' So you can ignore what I said, unless the script is meant to be portable to a non-Unix system, or you just want to be safe...

    --
    3dan
Re: use die with flock
by particle (Vicar) on Jul 24, 2003 at 15:11 UTC

    your locking method is problematic. the file may be locked by someone else, or modified after you open the file, but before you lock it.

    you can solve this and other file locking problems using the techniques outlined in Dominus's file locking tricks and traps.

    ~Particle *accelerates*

      No, the problem would only be there if you open the file for writing. But opening the file for append doesn't truncate the file, and the system (well, at least a Unix system) will seek to the end before you perform a write.

      Abigail