Index: /main/trunk/greenstone2/runtime-src/src/recpt/os_process.cpp
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/recpt/os_process.cpp	(revision 22182)
+++ /main/trunk/greenstone2/runtime-src/src/recpt/os_process.cpp	(revision 22183)
@@ -26,5 +26,6 @@
 #include "os_process.h"
 
-osprocess::osprocess(char* cmdline, OSProcessPipeMode mode)
+osprocess::osprocess(OSProcessPipeMode mode,
+		     char* prog_name, char* argv[], char* envp[])
   : mode_(mode)
 {}
@@ -54,22 +55,59 @@
 using namespace std;
 
+
+
 void test_uni_write_pipe()
 {
 #ifdef __WIN32__
-  char* prog_name = "c:\\Windows\\system32\\java.exe";
-  char* cmd_line = "java";
-  
-  //char* input_line = "echo hi there\n";
-  //char* prog_name  = "c:\\cygwin\\bin\\cat.exe";
-  //char* cmd_line   = "cat";
-#else
-  char* cmd_line = "/usr/bin/java";
-  //char* cmd_line = "java";
-#endif
-
-#ifdef __WIN32__
-  osprocesswindows* process = new osprocesswindows(cmd_line,uniRead);
-#else
-  osprocessunix* process = new osprocessunix(cmd_line,uniRead);
+  char* prog_name = "type";
+  char* argv[] = { "type", NULL } ;
+  
+#else
+  char* prog_name = "tr";
+  char* argv[] = { "tr", "[A-Z]", "[a-z]", NULL };
+#endif
+
+  cout << "<hr>" << endl;
+  cout << "<p>Unidirectional Write Test" << endl;
+  cout << "<p>  Converts uppercase letters to lowercase" << endl;
+  cout << "<p>  These are then sent to whereever the stdout of the child process goes" << endl;
+  cout << "<p>" << endl;
+
+#ifdef __WIN32__
+  osprocesswindows* process = new osprocesswindows(uniWrite,prog_name,argv);
+#else
+  osprocessunix* process = new osprocessunix(uniWrite,prog_name,argv);
+#endif
+  
+  char* buffer = "TESTING uniWirite IN CAP\nTesting uniWrite in Mixed Case\n";
+  int buffer_len = strlen(buffer);
+
+  if (!process->write(buffer,buffer_len)) {
+    cerr << "Error: failed to write to child process\n";
+  }
+
+  process->close();
+
+  process->wait();
+
+  delete process;
+}
+
+
+void test_uni_read_pipe()
+{
+  char* prog_name = "java";
+  char* argv[] = { "java", NULL };
+
+  cout << "<hr>" << endl;
+  cout << "<p>Unidirectional Read Test" << endl;
+  cout << "<p>  The output of 'java' is read in by this process and then sent to stdout" << endl;
+  cout << "<p>" << endl;
+
+
+#ifdef __WIN32__
+  osprocess* process = new osprocesswindows(uniRead,prog_name,argv);
+#else
+  osprocess* process = new osprocessunix(uniRead,prog_name,argv);
 #endif
   
@@ -86,7 +124,64 @@
 
 
+  // deleting object will also have the effect of closing any open handles
   delete process;
 
 }
+
+
+
+void test_bi_read_write_pipe()
+{
+#ifdef __WIN32__
+  char* prog_name = "type";
+  char* argv[] = NULL ;
+  
+#else
+  char* prog_name = "tr";
+  char* argv[] = { "tr", "[A-Z]", "[a-z]", NULL };
+#endif
+
+  // Converts uppercase letters to lowercase
+  // Answer is read back and then printed to STDOUT by this process
+
+  cout << "<hr>" << endl;
+  cout << "<p>Bidirectional Read/Write Test" << endl;
+  cout << "<p>  Converts uppercase letters to lowercase" << endl;
+  cout << "<p>  Data is sent to child process down pipe by this process" << endl;
+  cout << "<p>  Answer is read back from child process and printed to stdout" << endl;
+  cout << "<p>" << endl;
+
+#ifdef __WIN32__
+  osprocesswindows* process = new osprocesswindows(biReadWrite,prog_name,argv);
+#else
+  osprocessunix* process = new osprocessunix(biReadWrite,prog_name,argv);
+#endif
+  
+  char* write_buffer = "TESTING biReadWrite IN CAP\nTesting biReadWrite in Mixed Case\n";
+  int write_buffer_len = strlen(write_buffer);
+
+  if (!process->write(write_buffer,write_buffer_len)) {
+    cerr << "Error: failed to write to child process\n";
+  }
+
+  const int BufferSize = 1024;
+  char read_buffer[BufferSize];
+  process->close_write_pipe();
+
+  int bytes_read = 0;
+  do {
+    bytes_read = process->read(read_buffer,BufferSize);
+    if (bytes_read>0) {
+      fwrite(read_buffer,1,bytes_read,stdout);
+    }
+  } while (bytes_read==BufferSize);
+
+
+  process->close();
+
+  delete process;
+
+}
+
 
 int main()
@@ -100,5 +195,7 @@
   printf( "  <body>\n");
 
+  test_uni_read_pipe();
   test_uni_write_pipe();
+  test_bi_read_write_pipe();
 
   printf( "  </body>\n");
Index: /main/trunk/greenstone2/runtime-src/src/recpt/os_process.h
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/recpt/os_process.h	(revision 22182)
+++ /main/trunk/greenstone2/runtime-src/src/recpt/os_process.h	(revision 22183)
@@ -42,5 +42,7 @@
   
  public:
-  osprocess(char* cmdline, OSProcessPipeMode mode);
+  osprocess(OSProcessPipeMode mode,
+	    char* prog_name, char* argv[]=NULL, char* envp[]=NULL);
+
   virtual ~osprocess();
   
@@ -53,5 +55,7 @@
   virtual int write(char* buffer, const int buffer_len)=0;
   virtual int read(char* buffer, const int buffer_len)=0;
-  
+
+  virtual void wait()=0;
+
   virtual bool close_write_pipe(OSProcessWarnStatus warn_status=withWarning)=0;
   virtual bool close_read_pipe(OSProcessWarnStatus warn_status=withWarning)=0;
@@ -61,5 +65,4 @@
  protected:
   OSProcessPipeMode mode_;
-
 };
 
Index: /main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.cpp
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.cpp	(revision 22182)
+++ /main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.cpp	(revision 22183)
@@ -38,10 +38,12 @@
 
 #include <unistd.h>
+#include <sys/wait.h>
 
 #include "os_process_unix.h"
 
-osprocessunix::osprocessunix(char* cmdline, OSProcessPipeMode mode)
+osprocessunix::osprocessunix(OSProcessPipeMode mode,
+			     char* prog_name, char* argv[], char* envp[])
   : child_stdout_read_(-1), child_stdin_write_(-1),
-    osprocess(cmdline,mode)
+    osprocess(mode,prog_name,argv,envp)
 {
   
@@ -112,7 +114,11 @@
 
     
-    // execvp?
-    execve(cmdline, NULL, NULL);
-
+    // Used to be execve(), but this would appear not to search path for
+    // 'prog_name'. The alternative execvp() does search PATH and so is
+    // more compatible with how CreateProcess works for Windows
+
+    // Need to connect envp with externally defined '**environ' ??
+
+    execvp(prog_name,argv);
     
   }
@@ -178,5 +184,16 @@
 
 
-  
+void osprocessunix::wait()
+{
+  int child_status;
+  //cerr << "**** waiting ..." << endl;
+  ::waitpid(pid_,&child_status,0);
+
+  //cerr << "*** exit status = " << WEXITSTATUS(child_status) << endl;
+
+  //cerr << "**** done" << endl;
+}
+
+
 bool osprocessunix::close_write_pipe(OSProcessWarnStatus warn_status)
 {
Index: /main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.h
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.h	(revision 22182)
+++ /main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.h	(revision 22183)
@@ -34,9 +34,10 @@
 #include "os_process.h"
 
-class osprocessunix : osprocess
+class osprocessunix : public osprocess
 {
    
  public:
-  osprocessunix(char* cmd, OSProcessPipeMode mode);
+  osprocessunix(OSProcessPipeMode mode,
+		char* prog_name, char* argv[]=NULL, char* envp[]=NULL);
   virtual ~osprocessunix();
   
@@ -44,4 +45,6 @@
   virtual int write(char* buffer, const int buffer_len);
   
+  virtual void wait();
+
   virtual bool close_write_pipe(OSProcessWarnStatus warn_status=withWarning);
   virtual bool close_read_pipe(OSProcessWarnStatus warn_status=withWarning);
Index: /main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.cpp
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.cpp	(revision 22182)
+++ /main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.cpp	(revision 22183)
@@ -45,7 +45,9 @@
 {}
 
-osprocesswindows::osprocesswindows(char* cmdline, OSProcessPipeMode mode)
+osprocesswindows::osprocesswindows(OSProcessPipeMode mode,
+				   char* prog_name, char* argv[]=NULL, 
+				   char* envp[])
   : child_stdout_read_(NULL), child_stdin_write_(NULL),
-    osprocess(cmdline,mode)
+    osprocess(mode,prog_name,argv,envp)
 {
   HANDLE child_stdin_read = NULL;
@@ -102,6 +104,20 @@
   si.hStdInput = child_stdin_read;
   
+  text_t cmd_line = "";
+  if (argv != NULL) {
+    int i=0;
+    while (argv[i] != NULL) {
+      if (i>0) {
+	cmd_line += " ";
+      }
+      cmd_line += "\"" + argv[i] + "\"";
+      i++;
+    }
+  }
+
+  char* cmd_line_cstr = cmd_line.getcstr();
+
   int rv = CreateProcess(NULL,    // no application name
-			 cmdline, 
+			 cmd_line_cstr, 
 			 NULL, 
 			 NULL,    // no process or thread security attribues 
@@ -112,6 +128,9 @@
 			 &si, 
 			 &pi_);    // process info filled out as a result
+
+  delete [] cmd_line_cstr;
+
   if (!rv) {
-    cerr << "os_process_windows(): Error creating process" << endl;
+    cerr << "os_process_windows(): Error creating child process" << endl;
   }
 
@@ -119,9 +138,9 @@
 
   if (!CloseHandle(child_stdout_write)) {
-    cerr <<  "os_process_windows(): Error closing StdOutWr Handle" << endl;
+    cerr <<  "os_process_windows(): Error closing child's StdOut Write Handle" << endl;
   }
 
   if (!CloseHandle(child_stdin_read)) {
-    cerr << "os_process_windows(): Error closing StdInRd Handle" << endl;
+    cerr << "os_process_windows(): Error closing child's StdIn Read Handle" << endl;
   }
 }  
@@ -170,4 +189,8 @@
 
 
+void osprocesswindows::wait()
+{
+  WaitForSingleObject(pi_.hProcess, INFINITE);
+}
 
   
Index: /main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.h
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.h	(revision 22182)
+++ /main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.h	(revision 22183)
@@ -35,12 +35,15 @@
 #include <windows.h> 
 
-class osprocesswindows : osprocess
+class osprocesswindows : public osprocess
 {
 public:
-  osprocesswindows(char* cmdline, OSProcessPipeMode mode);
+  osprocesswindows(OSProcessPipeMode mode,
+		   char* prog_name, char* argv[]=NULL, char* envp[]=NULL);
   virtual ~osprocesswindows();
 
   virtual int read(char* buffer, const int buffer_len);
   virtual int write(const char* buffer, const int buffer_len);
+
+  virtual void wait();
 
   virtual bool close_write_pipe(OSProcessWarnStatus warn_status);
