Index: trunk/Ohana/src/opihi/pantasks/ControllerOps.c
===================================================================
--- trunk/Ohana/src/opihi/pantasks/ControllerOps.c	(revision 4697)
+++ trunk/Ohana/src/opihi/pantasks/ControllerOps.c	(revision 4705)
@@ -1,15 +1,17 @@
 # include "psched.h"
-# define CONTROLLER_TIMEOUT 20
+/* adding a new host can delay controller up to a second or so */
+# define CONTROLLER_TIMEOUT 200
 # define CONNECT_TIMEOUT 300
 
 /* local static variables to hold the connection to the controller */
-static int status = FALSE;
+static int ControllerStatus = FALSE;
 static int stdin_cntl, stdout_cntl, stderr_cntl;
 static IOBuffer stdout_buffer;
 static IOBuffer stderr_buffer;
+static int ControllerPID = 0;
 
 /* test if the controller is running */
 int CheckControllerStatus () {
-  return (status);
+  return (ControllerStatus);
 }
 
@@ -29,5 +31,5 @@
 int CheckControllerJobStatus (Job *job) {
 
-  int outstate;
+  int outstate, status;
   char cmd[128], status_string[64];
   char *p;
@@ -41,19 +43,19 @@
   switch (status) {
     case CONTROLLER_DOWN:
-      fprintf (stderr, "controller is down\n");
+      if (VerboseMode()) fprintf (stderr, "controller is down\n");
       FreeIOBuffer (&buffer);
       return (FALSE);
 
     case CONTROLLER_HUNG:
-      fprintf (stderr, "controller is not responding\n");
+      if (VerboseMode()) fprintf (stderr, "controller is not responding\n");
       FreeIOBuffer (&buffer);
       return (FALSE);
 
     case CONTROLLER_GOOD:
-      fprintf (stderr, "message received (CheckControllerJobStatus)\n");
+      if (VerboseMode()) fprintf (stderr, "message received (CheckControllerJobStatus)\n");
       break;
 
     default:
-      fprintf (stderr, "unknown status for controller command: programming error\n");  
+      if (VerboseMode()) fprintf (stderr, "unknown status for controller command: programming error\n");  
       exit (1);
   }
@@ -105,8 +107,5 @@
 
   /* send command to get appropriate channel */
-  ALLOCATE (line, char, MAX (1, strlen(cmd) + 15));
-  sprintf (line, "%s %d\n", cmd, pid);
-  status = write (stdin_cntl, line, strlen(line));
-  free (line);
+  status = write_fmt (stdin_cntl, "%s %d\n", cmd, pid);
 
   /* is pipe still open? */
@@ -126,5 +125,5 @@
   if (status == -1) return (CONTROLLER_HUNG);
 
-  fprintf (stderr, "message received (GetJobOutput : %s)\n", cmd);  
+  if (VerboseMode()) fprintf (stderr, "message received (GetJobOutput : %s)\n", cmd);  
   /* drop extra bytes from pcontrol (not pclient:job) */
   buffer[0].Nbuffer = Nstart + Nbytes;
@@ -161,5 +160,5 @@
 
   /* construct the controller command portion */
-  if (!strcmp (job[0].task[0].host, "NONE")) {
+  if (!strcasecmp (job[0].task[0].host, "ANYHOST")) {
     sprintf (cmd, "job");
   } else {
@@ -177,10 +176,7 @@
   }
 
-  fprintf (stderr, "sending command to controller: %s\n", cmd);
   InitIOBuffer (&buffer, 0x100);
   ControllerCommand (cmd, CONTROLLER_PROMPT, &buffer);
   free (cmd);
-
-  fprintf (stderr, "response from controller: %s\n", buffer.buffer);
 
   /* extract the job PID from the controller response */
@@ -203,9 +199,9 @@
   char *p;
   char **argv, cmd[128];
-  int i, pid;
+  int i, pid, status;
   int stdin_fd[2], stdout_fd[2], stderr_fd[2];
   IOBuffer buffer;
 
-  if (status) return (TRUE);
+  if (ControllerStatus) return (TRUE);
 
   if (VarConfig ("CONTROLLER", "%s", cmd) == NULL) strcpy (cmd, "pcontrol");
@@ -262,6 +258,5 @@
 
   /* send handshake command */
-  sprintf (cmd, "echo CONNECTED\n");
-  status = write (stdin_fd[1], cmd, strlen(cmd));
+  status = write_fmt (stdin_fd[1], "echo CONNECTED\n");
   if ((status == -1) && (errno == EPIPE)) goto pipe_error;
 
@@ -286,4 +281,6 @@
   InitIOBuffer (&stderr_buffer, 0x100);
 
+  ControllerPID = pid;
+  ControllerStatus = TRUE;
   fprintf (stderr, "Connected\n");
   return (TRUE);
@@ -316,13 +313,8 @@
   FlushIOBuffer (buffer);
 
-  fprintf (stderr, "send: %s\n", cmd);
-
-  /* send command to client (adding on \n) */
-  ALLOCATE (line, char, MAX (1, strlen(cmd)));
-  sprintf (line, "%s\n", cmd);
-  status = write (stdin_cntl, line, strlen(line));
-  free (line);
-
-  /* is pipe still open? */
+  if (VerboseMode()) fprintf (stderr, "send: %s\n", cmd);
+
+  /* send command, is pipe still open? */
+  status = write_fmt (stdin_cntl, "%s\n", cmd);
   if ((status == -1) && (errno == EPIPE)) return (CONTROLLER_DOWN);
   
@@ -335,7 +327,16 @@
     if (status == -1) usleep (10000);
   }
-  if (status ==  0) return (CONTROLLER_DOWN);
+  if (status ==  0) {
+    ControllerStatus = FALSE;
+    return (CONTROLLER_DOWN);
+  }
   if (status == -1) return (CONTROLLER_HUNG);
-  /* fprintf (stderr, "buffer.buffer: %s\n", buffer[0].buffer); */
+
+  /* need to strip off the prompt */
+  line = memstr (buffer[0].buffer, response, buffer[0].Nbuffer);
+  if (line != NULL) {
+    buffer[0].Nbuffer = line - buffer[0].buffer;
+    bzero (buffer[0].buffer + buffer[0].Nbuffer, buffer[0].Nalloc - buffer[0].Nbuffer);
+  }
   return (CONTROLLER_GOOD);
 }
@@ -345,5 +346,5 @@
   int Nread;
 
-  if (!status) return (TRUE);
+  if (!ControllerStatus) return (TRUE);
 
   /* read stdout buffer */
@@ -390,5 +391,5 @@
   IOBuffer buffer;
 
-  if (!CheckControllerStatus()) return (TRUE);
+  if (!ControllerStatus) return (TRUE);
 
   sprintf (cmd, "kill %d", job[0].pid);
@@ -403,15 +404,24 @@
 int QuitController () {
 
-  int status;
+  int i, status, waitstatus, result;
   char cmd[128];
   IOBuffer buffer;
 
-  if (!CheckControllerStatus()) return (TRUE);
+  if (!ControllerStatus) return (TRUE);
 
   sprintf (cmd, "quit");
   InitIOBuffer (&buffer, 0x100);
   status = ControllerCommand (cmd, CONTROLLER_PROMPT, &buffer);
-  return (TRUE);
-}
-
-/* memstr returns a view, not an allocated string : don't free */
+  ControllerStatus = FALSE;
+  result = waitpid (ControllerPID, &waitstatus, WNOHANG);
+  for (i = 0; (i < 10) && (result == 0); i++) {
+    usleep (10000);  /* 10 ms is min */
+    result = waitpid (ControllerPID, &waitstatus, WNOHANG);
+  }
+  ControllerPID = 0;
+  close (stdin_cntl);
+  close (stdout_cntl);
+  close (stderr_cntl);
+
+  return (TRUE);
+}
