--- loncom/lonmaxima 2006/03/03 23:41:38 1.5 +++ loncom/lonmaxima 2006/03/04 06:44:11 1.8 @@ -3,7 +3,7 @@ # The LearningOnline Network with CAPA # Connect to MAXIMA CAS # -# $Id: lonmaxima,v 1.5 2006/03/03 23:41:38 albertel Exp $ +# $Id: lonmaxima,v 1.8 2006/03/04 06:44:11 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -52,7 +52,6 @@ my $pidfile; # my $port; # path to UNIX socket file my %perlvar; # configuration file info my $lastlog; # last string that was logged - use vars qw($PREFORK $MAX_CLIENTS_PER_CHILD %children $children $status $pidfile $port %perlvar $lastlog); @@ -65,23 +64,28 @@ sub maximareply { unless ($cmd=~/\;\n$/) { $cmd.=";\n"; } my ($cmd_in, $cmd_out, $cmd_err); - my $pid = open3($cmd_in, $cmd_out, $cmd_err, 'maxima'); - $children{$pid} = 1; + my $maximapid = open3($cmd_in, $cmd_out, $cmd_err, 'maxima'); + $children{$maximapid} = 1; print $cmd_in $cmd; close($cmd_in); &status("Command sent"); + $SIG{ALRM} = sub { kill 9 => $maximapid; }; + alarm(5); + no strict 'refs'; + my $selector = IO::Select->new(); + $selector->add($cmd_err, $cmd_out); - while (my @ready = $selector->can_read) { + while (my @ready = $selector->can_read()) { foreach my $fh (@ready) { if (fileno($fh) == fileno($cmd_err)) { $error.=<$cmd_err>; } else { - my $line = scalar <$cmd_out>; + my $line = scalar(<$cmd_out>); if ($line=~/^(\(\%o|\s)/) { $line=~s/^\(.*\)/ /; $reply.=$line; @@ -90,8 +94,11 @@ sub maximareply { $selector->remove($fh) if eof($fh); } } + alarm(0); + $SIG{ALRM} = 'DEFAULT'; close($cmd_out); close($cmd_err); + use strict 'refs'; &status("Command processed"); return ($reply,$error,$exitstatus); } @@ -101,13 +108,13 @@ sub REAPER { # ta # and MAXIMA processes $SIG{CHLD} = \&REAPER; my $pid = wait; - $children --; - delete $children{$pid}; + $children--; + delete($children{$pid}); } sub HUNTSMAN { # signal handler for SIGINT local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children - kill 'INT' => keys %children; + kill('INT' => keys(%children)); unlink($pidfile); unlink($port); &logthis('---- Shutdown ----'); @@ -197,7 +204,7 @@ if (-e $pidfile) { my $lfh=IO::File->new("$pidfile"); my $pide=<$lfh>; chomp($pide); - if (kill 0 => $pide) { die "already running"; } + if (kill(0 => $pide)) { die "already running"; } } # ------------------------------------------------------- Listen to UNIX socket @@ -208,26 +215,25 @@ $port = "$perlvar{'lonSockDir'}/maximaso unlink($port); -my $server; -unless ( - $server = IO::Socket::UNIX->new(Local => $port, - Type => SOCK_STREAM, - Listen => 10 ) - ) { - my $st=120+int(rand(240)); - &logthis( - "WARNING: ". - "Can't make server socket ($st secs): .. exiting"); - sleep($st); - exit; - }; +my $server = IO::Socket::UNIX->new(Local => $port, + Type => SOCK_STREAM, + Listen => 10 ); +if (!$server) { + my $st=120+int(rand(240)); + + &logthis("WARNING: ". + "Can't make server socket ($st secs): .. exiting"); + + sleep($st); + exit; +} # ---------------------------------------------------- Fork once and dissociate my $fpid=fork; exit if $fpid; -die "Couldn't fork: $!" unless defined ($fpid); +die("Couldn't fork: $!") unless defined($fpid); POSIX::setsid() or die "Can't start new session: $!"; @@ -239,11 +245,8 @@ print PIDSAVE "$$\n"; close(PIDSAVE); &logthis("CRITICAL: ---------- Starting ----------"); &status('Starting'); - - - - + # Fork off our children. for (1 .. $PREFORK) { &make_new_child($server); @@ -269,14 +272,14 @@ sub make_new_child { # block signal for fork my $sigset = POSIX::SigSet->new(SIGINT); sigprocmask(SIG_BLOCK, $sigset) - or die "Can't block SIGINT for fork: $!\n"; + or die("Can't block SIGINT for fork: $!\n"); - die "fork: $!" unless defined (my $pid = fork); + die("fork: $!") unless defined(my $pid = fork); if ($pid) { # Parent records the child's birth and returns. sigprocmask(SIG_UNBLOCK, $sigset) - or die "Can't unblock SIGINT for fork: $!\n"; + or die("Can't unblock SIGINT for fork: $!\n"); $children{$pid} = 1; $children++; return; @@ -286,7 +289,7 @@ sub make_new_child { # unblock signals sigprocmask(SIG_UNBLOCK, $sigset) - or die "Can't unblock SIGINT for fork: $!\n"; + or die("Can't unblock SIGINT for fork: $!\n"); &process_requests($server);