Index: /trunk/Ohana/src/opihi/cmd.basic/shell.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/shell.c	(revision 15867)
+++ /trunk/Ohana/src/opihi/cmd.basic/shell.c	(revision 15868)
@@ -3,23 +3,69 @@
 int shell (int argc, char **argv) {
   
-  int i, status;
-  char line[2048], tmp[1024];
+  int i, pid;
+  int exit_status;
+  int wait_status;
+  int result;
+  char **args;
 
-  bzero (tmp, 1024);
-  bzero (line, 2048);
+  ALLOCATE (args, char *, argc);
+  for (i = 1; i < argc; i++) {
+    args[i-1] = argv[i];
+  }
+  args[i-1] = NULL;
 
-  for (i = 1; i < argc; i++) {
-    sprintf (tmp, "%s ", argv[i]);
-    strcat (line, tmp);
+  // use execvp to enable a timeout on the system call 
+  pid = fork ();
+  if (!pid) { /* must be child process */
+    execvp (args[0], args);
+    exit (1);
+  }
+  free (args);
+  
+  // wait for process to finish or timeout
+  for (i = 0; i < 200; i++) {
+    result = waitpid (pid, &wait_status, WNOHANG);
+    switch (result) {
+      case -1:   // error on waitpid
+	switch (errno) {
+	  case ECHILD:
+	    gprint (GP_ERR, "unknown PID, not a child process: %d\n", pid);
+	    return (FALSE);
+	  default:
+	    gprint (GP_ERR, "unexpected response to waitpid: %d\n", result);
+	    abort();
+	}
+	break;
+
+      case 0:   // child not yet exited
+	usleep (10000);
+	continue;
+
+      default:
+	if (result != pid) {
+	  gprint (GP_ERR, "waitpid error: mis-matched PID (%d vs %d).  programming error\n", result, pid);
+	  abort();
+	}
+	if (WIFEXITED(wait_status)) {
+	  exit_status = WEXITSTATUS(wait_status);
+	  if (exit_status) {
+	    return FALSE;
+	  } else {
+	    return TRUE;
+	  }
+	}
+	if (WIFSIGNALED(wait_status)) {
+	  gprint (GP_ERR, "job %d exited on signal %d\n", pid, WTERMSIG(wait_status));
+	  return (FALSE);
+	}
+	if (WIFSTOPPED(wait_status)) {
+	  gprint (GP_ERR, "waitpid returns 'stopped' programming error\n");
+	  abort();
+	}
+    }
   }
 
-  strcat (line, "\n");
-  status = system (line);
-
-  if (status) {
-    return (FALSE);
-  } else {
-    return (TRUE);
-  }
+  gprint (GP_ERR, "timeout on %d\n", pid);
+  return (FALSE);
 }
 
