--- loncom/interface/printout.pl 2007/10/11 22:49:49 1.128 +++ loncom/interface/printout.pl 2008/03/10 10:24:49 1.130 @@ -1,7 +1,7 @@ #!/usr/bin/perl # CGI-script to run LaTeX, dvips, ps2ps, ps2pdf etc. # -# $Id: printout.pl,v 1.128 2007/10/11 22:49:49 albertel Exp $ +# $Id: printout.pl,v 1.130 2008/03/10 10:24:49 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -43,6 +43,7 @@ use LONCAPA::Configuration; use strict; +my $busy_wait_timeout = 20; # Determine if a user is operating as a student for this course/domain. #Parameters: @@ -379,14 +380,14 @@ foreach $texfile (@texfile) { my $dvi_file= $name_file; $dvi_file =~ s/\.tex/$name_range\.dvi/; &busy_wait_command("latex $name_file 1>/dev/null 2>/dev/null", "for $status_statement now LaTeXing file", - \%prog_state,$dvi_file); + \%prog_state,$dvi_file, $busy_wait_timeout); if ($tableofcontents eq 'yes') { &busy_wait_command("latex $name_file 1>/dev/null 2>/dev/null", "for $status_statement First LaTeX of file for table of contents", - \%prog_state,$dvi_file); + \%prog_state,$dvi_file, $busy_wait_timeout); &busy_wait_command("latex $name_file 1>/dev/null 2>/dev/null", "for $status_statement Second LaTeX of file for table of contents", - \%prog_state,$dvi_file); + \%prog_state,$dvi_file,$busy_wait_timeout); } #to create table of contents my $idxname=$name_file; $idxname=~s/\.tex$/\.idx/; @@ -396,7 +397,7 @@ foreach $texfile (@texfile) { \%prog_state,$idxname); &busy_wait_command("latex $name_file 1>/dev/null 2>/dev/null", "for $status_statement now LaTeXing file for index section", - \%prog_state,$dvi_file); + \%prog_state,$dvi_file, $busy_wait_timeout); } #to create index #Do we have a latex error in the log file? my $logfilename = $texfile; $logfilename =~ s/\.tex$/\.log/; @@ -512,14 +513,14 @@ foreach $texfile (@texfile) { # &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement first latex to repaginate", - \%prog_state, $name_file); + \%prog_state, $name_file,$busy_wait_timeout); if ($tableofcontents eq 'yes') { &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement second latex to repaginate", - \%prog_state, $name_file); + \%prog_state, $name_file,$busy_wait_timeout); &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement third latex to repaginate", - \%prog_state, $name_file); + \%prog_state, $name_file,$busy_wait_timeout); } if ($tableofindex eq 'yes') { my $idxname = $latex_file; @@ -529,7 +530,7 @@ foreach $texfile (@texfile) { \%prog_state, $idxname); &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement now Recreting index (latex)", - \%prog_state, $dvi_file); + \%prog_state, $dvi_file,$busy_wait_timeout); } &busy_wait_command("$comma $name_file 1>/dev/null 2>/dev/null", @@ -685,14 +686,14 @@ foreach $texfile (@texfile) { &repaginate($new_name_file, $latex_file, $numberofcolumns); &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement first latex to repaginate", - \%prog_state, $name_file); + \%prog_state, $name_file, $busy_wait_timeout); if ($tableofcontents eq 'yes') { &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement second latex to repaginate", - \%prog_state, $name_file); + \%prog_state, $name_file, $busy_wait_timeout); &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement third latex to repaginate", - \%prog_state, $name_file); + \%prog_state, $name_file, $busy_wait_timeout); } if ($tableofindex eq 'yes') { my $idxname = $latex_file; @@ -702,7 +703,7 @@ foreach $texfile (@texfile) { \%prog_state, $idxname); &busy_wait_command("latex $latex_file 1>/dev/null 2>/dev/null", "for $status_statement now Recreting index (latex)", - \%prog_state, $dvi_file); + \%prog_state, $dvi_file, $busy_wait_timeout); } &busy_wait_command("$comma $name_file 1>/dev/null 2>/dev/null", "for $status_statement dvips to repaginate", @@ -794,9 +795,17 @@ my $done; sub REAPER { $done=1; } - +# +# Execute a command updating the status window as the command's +# output file builds up (at intervals of a second). +# +# If the timeout argument defined, then if that many seconds +# elapses without an increase in the size of the output file, +# the command will be killed (this deals with the case when +# latex crawls into an infinite loop). +# sub busy_wait_command { - my ($command,$message,$progress_win,$output_file)=@_; + my ($command,$message,$progress_win,$output_file, $timeout)=@_; $SIG{CHLD} = \&REAPER; $done=0; @@ -804,12 +813,30 @@ sub busy_wait_command { if ($advanced_role) { &Apache::lonhtmlcommon::Update_PrgWin('',$progress_win,$message); } + my $last_size = 0; + my $unchanged_time = 0; while(!$done) { sleep 1; my $extra_msg; if ($output_file) { my $size=(stat($output_file))[7]; $extra_msg=", $size bytes generated"; + if ($size == $last_size) { + $unchanged_time++; + if ($timeout && ($unchanged_time > $timeout)) { + print "

Operation timed out!!!

\n"; + print "

Executing $command, The output file $output_file did not grow\n"; + print "after $timeout seconds. This may indicate $command\n"; + print "is in an infinite loop."; + print "See if printing fewer copies helps. Please contact LonCAPA\n"; + print "support about this in any event"; + print "

"; + kill(9, $pid); # Reaper will do the rest...I hope there's errors in the log. + } + } else { + $last_size = $size; + $unchanged_time = 0; + } } if ($advanced_role) { &Apache::lonhtmlcommon::Update_PrgWin('',$progress_win,