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

Script can not open the transcripts.txt file I think. Its an old perl script. Was working fine until a few chatters got to posting a lot together and it crashed.
#!/usr/bin/perl #print "Content-type:text/html\n\n"; use CGI::Carp qw(fatalsToBrowser); #LITERALS #-------- $LOCK_SH = 1; $LOCK_EX = 2; $LOCK_NB = 4; $LOCK_UN = 8; $TRUE = 1; $FALSE = 0; #GLOBALS #------- $client = "chat.pl#anchor1"; $point_gif = "http://www.themegaphone.net/point.gif"; $webchat_logo = "/mbslogo2sm.gif "; $about_local_server = "http://themegaphone.net"; $local_tz = "GMT (-0000 GMT)"; $read_block_size = 512; $num_context_paras = 0; $num_context_paras_when_starting = 10; $para_mark_size = 7; # 7 digits (space padded) $back_jump = 10; $way_back_when = 40; # get the form &ReadParse; $talkfile ="transcripts/" . $in{room} . ".txt"; $last_read_para = $in{last_read_para}; $wants_dates_printed = $in{wants_dates_printed}; $back_para = $in{back_para}; # we've changed to letting you specify how far back you want to scroll # we're leaving the old code in case we go back if($in{Back} > 0) { $back = $TRUE; $back_para = $back_para - $back_jump; ($back_para < 1) && ($back_para = 1); # $last_read_para = $back_para; $last_read_para = $last_read_para - $in{Back}; ($last_read_para < 1) && ($last_read_para = 1); } # open a (properly initialized) transcript file # later: if need to die, put text in some log file somewhere open (TRANSCRIPT, "+<$talkfile") || die "Client can't open transcript file"; # If the user input any text, add it to transcript file ($in{InputText} ne "" && $back eq "") && &add_to_transcript; # Update the output area or send error message if nothing new &output_new_form; exit;

Replies are listed 'Best First'.
Re: Chat Error
by sgifford (Prior) on Dec 31, 2005 at 17:19 UTC
    You'll need to lock the file while you're appending to it. You'll probably want to open the file in append mode to do this, which should tell your OS to be cleverer about going to the end of the file before writing, and then rewind it to the beginning. Here's a brief demo:
    use warnings; use strict; use Fcntl ':flock'; our $talkfile="t44.talk"; open(TRANSCRIPT,"+>>$talkfile") or die "Client can't open transcript file: $!"; # Read the file with a shared lock flock(TRANSCRIPT,LOCK_SH) or die "Couldn't lock transcript: $!\n"; seek(TRANSCRIPT,0,0) or die "Couldn't rewind transcript file: $!\n"; print <TRANSCRIPT>; # Write the file with an exclusive lock flock(TRANSCRIPT,LOCK_EX); print TRANSCRIPT "ran at ",time,"\n"; # Unlock the file when you're done flock(TRANSCRIPT,LOCK_UN);

    The lock will be released automatically when your program exits, so it's OK to die while holding the lock. Opening the file in append mode will tell perl or the OS to seek to the end of the file before writing anything.