diff src/toplev.cc @ 3060:9c6cd52f3f5a

[project @ 1997-06-25 18:30:40 by jwe]
author jwe
date Wed, 25 Jun 1997 18:32:50 +0000
parents f491f232cb09
children af7ec9d3a5e6
line wrap: on
line diff
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -301,10 +301,22 @@
 
 // Execute a shell command.
 
+static int cmd_status = 0;
+
+static void
+cmd_death_handler (pid_t, int status)
+{
+  cmd_status = status;
+}
+
 static void
 cleanup_iprocstream (void *p)
 {
-  delete static_cast<iprocstream *> (p);
+  iprocstream *cmd = static_cast<iprocstream *> (p);
+
+  octave_child_list::remove (cmd->pid ());
+
+  delete cmd;
 }
 
 static octave_value_list
@@ -314,41 +326,53 @@
 
   iprocstream *cmd = new iprocstream (cmd_str.c_str ());
 
-  unwind_protect::add (cleanup_iprocstream, cmd);
+  cmd_status = -1;
 
-  int status = 127;
-
-  if (cmd && *cmd)
+  if (cmd)
     {
-      ostrstream output_buf;
+      octave_child_list::insert (cmd->pid (), cmd_death_handler);
+
+      unwind_protect::add (cleanup_iprocstream, cmd);
+
+      if (*cmd)
+	{
+	  ostrstream output_buf;
 
-      char ch;
-      while (cmd->get (ch))
-	output_buf.put (ch);
+	  char ch;
+	  while (cmd->get (ch))
+	    output_buf.put (ch);
 
-      status = cmd->close ();
+	  cmd->close ();
+
+	  // One way or another, cmd_death_handler should be called
+	  // when the process exits, and it will save the exit status
+	  // of the command in cmd_status.
 
-      // The value in status is as returned by waitpid.  If the
-      // process exited normally, extract the actual exit status of
-      // the command.  Otherwise, return 127 as a failure code.
+	  // The value in cmd_status is as returned by waitpid.  If
+	  // the process exited normally, extract the actual exit
+	  // status of the command.  Otherwise, return 127 as a
+	  // failure code.
 
-      if (WIFEXITED (status))
-	status = WEXITSTATUS (status);
+	  if (WIFEXITED (cmd_status))
+	    cmd_status = WEXITSTATUS (cmd_status);
+	  else
+	    cmd_status = 127;
 
-      output_buf << ends;
+	  output_buf << ends;
 
-      char *msg = output_buf.str ();
+	  char *msg = output_buf.str ();
 
-      retval(1) = static_cast<double> (status);
-      retval(0) = msg;
+	  retval(1) = (double) cmd_status;
+	  retval(0) = msg;
 
-      delete [] msg;
+	  delete [] msg;
+	}
+
+      unwind_protect::run ();
     }
   else
     error ("unable to start subprocess for `%s'", cmd_str.c_str ());
 
-  unwind_protect::run ();
-
   return retval;
 }