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

Hi monks,

I've a perl cgi program hosted at the free hosting site netfirms. I use flat files for the database and the program has worked fine for almost a year - adding and updating entries into flat files of 40-50 lines each. If an update on an entry is required, usually only about two files are affected.

Today, something happened to one of the flat files. It became corrupted! I'm puzzled how that happened. I've never experienced anything like that with my other scripts on other sites (also using flat files).

My question is: What could have caused the file to become corrupted? Could it be a result of someone updating the file and another person accessing the script which required accessing the same file at the same instant? Or is it something to do with the server?

Thanks in anticipation :)

kiat

Replies are listed 'Best First'.
Re: Text file got corrupted?
by Zaxo (Archbishop) on Oct 01, 2003 at 04:00 UTC

    I think your simultaneous access theory is probably correct. The cure is flock, which is not always easy to get right. Read the docs and search here for working examples.

    After Compline,
    Zaxo

Re: Text file got corrupted?
by jonnyfolk (Vicar) on Oct 01, 2003 at 04:10 UTC

    Yes, it could have been that. Or that. Or something entirely different. Are your files flocked, for instance? I would imagine that there's an anomoly in the script somewhere which only triggers in a rare set of circumstances. Which have just happened!

    The only thing to do is to start going through your code with a fine toothcomb, and if you want some help with parts of it, then come back with some code snippets for the Monks to look at.

    PS - hope you backed up!

      Thanks, jonnyfolk!

      I'm adding a snippnet of a typical modify subroutine so other monks here and yourself can help me pinpoint the problem area.

      # When I test the script locally in Windows, I need # to suppress flock because it's not supported # In use in the server, $flock is set to 1. my $flock = 1; sub modify { my $tmp_file = get_file(); open(FILE,"+<$tmp_file") || error("The file $tmp_file cannot be foun +d!"); flock(FILE, 2) || die $! if $flock; chomp(my @lines = <FILE>); seek(FILE,0,0); truncate(FILE,0) || die $!; # could have used foreach here for (0..@lines) { my ($name, $score) = split/\|/, $lines[$_]; $score++; print FILE "$name|$score\n" if ($name); } close FILE; }
      Please help me look at the code to see if I'm missing something :)
        Hello kiat,

        I'm sure the other monks will let me know if I am on the wrong track, but I think you may have a problem in the line flock(FILE, 2) || die $! if $flock;

        By putting in the phrase "if $flock" what you are saying is that the script should die if the lock is "shared for reading" but not if it is not locked at all! What I think would be preferable is simply:

        flock(FILE, 2) || die "can't print to $tmp_file: $!";
        as this would force the script to die on any circumstances other than a "locked for writing" situation.

        Addendum: It also seems a little strange to me that you go to the trouble of defining a variable $flock but then use flock(FILE, 2). Though I can see that you wouldn't want to mistakenly do anything else but "2" in a writing situation I would think that consistent use of one or other methods (and making sure that usage is correct in the chosen method) is better than being inconsistent and inviting anomolies to occur.
Re: Text file got corrupted?
by chanio (Priest) on Oct 01, 2003 at 06:48 UTC
    It happened to me. I guess that I would try to read about using -T at the SheBang (#!/usr/bin/perl -wT).

    And did you consider using ? ...

    use CGI::Safe   qw/:standard taint/;

    You could make the compiler advise you more precisely to your situation by pointing out the lines that are nor written securely. And if you can't solve those situations you can always copy your conflicting code here... Or, remove the -T and forget about the complains until you understand them better. (You'ld better not :)