--- loncom/lonmaxima	2006/03/03 23:41:38	1.5
+++ loncom/lonmaxima	2006/03/04 06:56:10	1.10
@@ -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.10 2006/03/04 06:56:10 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,29 @@ 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);
+
     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)) {
+	    if (ref($fh) 
+		&& ref($cmd_err)
+		&& 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 +95,11 @@ sub maximareply {
 	    $selector->remove($fh) if eof($fh);
 	}
     }
-    close($cmd_out);
-    close($cmd_err);
+    alarm(0);
+    $SIG{ALRM} = 'DEFAULT';
+    if (ref($cmd_out)) { close($cmd_out); }
+    if (ref($cmd_err)) { close($cmd_err); }
+
     &status("Command processed");
     return ($reply,$error,$exitstatus);
 }
@@ -101,13 +109,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 +205,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 +216,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(
-         "<font color=blue>WARNING: ".
-         "Can't make server socket ($st secs):  .. exiting</font>");
-       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("<font color=blue>WARNING: ".
+	     "Can't make server socket ($st secs):  .. exiting</font>");
+
+    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,20 +246,17 @@ print PIDSAVE "$$\n";
 close(PIDSAVE);
 &logthis("<font color='red'>CRITICAL: ---------- Starting ----------</font>");
 &status('Starting');
- 
- 
-
-
      
+
+# Install signal handlers.
+$SIG{CHLD} = \&REAPER;
+$SIG{INT}  = $SIG{TERM} = \&HUNTSMAN;
+ 
 # Fork off our children.
 for (1 .. $PREFORK) {
     &make_new_child($server);
 }
  
-# Install signal handlers.
-$SIG{CHLD} = \&REAPER;
-$SIG{INT}  = $SIG{TERM} = \&HUNTSMAN;
- 
 # And maintain the population.
 while (1) {
     &status('Parent process, sleeping');
@@ -269,14 +273,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 +290,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);