| 
				
			 | 
			
			 | 
			@@ -25,6 +25,7 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/types.h>
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/wait.h>
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <signal.h>
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/select.h>
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <cstring>
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <cerrno>
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -77,6 +78,13 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    exitCode = 0;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  size_t
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  Child::numBytesAvailable() const {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return readStreambuf.numBytesAvailable();
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  void
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  Child::run() {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -219,7 +227,7 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      throw std::runtime_error("Error creating pipe for stdin:  " +
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						       getErrorText());
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pipe(childStdOutPipe, O_NONBLOCK) != 0) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pipe(childStdOutPipe) != 0) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      close(childStdInPipe[0]);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      close(childStdInPipe[1]);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      throw std::runtime_error("Error creating pipe for stdout:  " +
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -487,9 +495,34 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  size_t
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    Child::ReadStreambuf::numBytesAvailable() const {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    size_t nBytesAvailable =  egptr() - gptr();
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    fd_set readFd;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int retVal;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    struct timeval timeout = {0, 0};
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    FD_ZERO(&readFd);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    FD_SET(inputFileDescriptor, &readFd);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // Check if input is available.
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    retVal = select(inputFileDescriptor + 1, &readFd, NULL, NULL, &timeout);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (-1 == retVal) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      throw std::runtime_error("Error from select(): " + getErrorText());
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } else if (retVal > 0) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				nBytesAvailable++;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return nBytesAvailable;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  std::streambuf::int_type
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  Child::ReadStreambuf::underflow() {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << "underflow()." << std::endl; // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // Check for empty buffer.
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (gptr() < egptr()) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -497,7 +530,7 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      return traits_type::to_int_type(*gptr());
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << "need to fill buffer." << std::endl; // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // Need to fill the buffer.
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    char *base = &(buffer.front());
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    char *start = base;
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -523,10 +556,18 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#else
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ssize_t nBytesRead;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << "Requesting read of " << buffer.size() - (start - base)
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				      << " bytes" << std::endl; // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    nBytesRead = read(inputFileDescriptor,
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					      start,
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					      buffer.size() - (start - base));
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << "nBytesRead:  " << nBytesRead << std::endl; // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (int i = 0; i < nBytesRead; i++) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      std::cout << (char) start[i];
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << std::endl;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // end of debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (-1 == nBytesRead) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      return traits_type::eof();
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -540,6 +581,8 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // Update buffer pointers.
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    setg(base, start, start + nBytesRead);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << "underflow() return." << std::endl; // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return traits_type::to_int_type(*gptr());
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  }
 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -598,6 +641,15 @@ namespace CodeDweller { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ssize_t nBytesWritten;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    nBytesWritten = write(outputFileDescriptor, pbase(), nBytes);
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // debug
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << "flushBuffer().  Requested to write " << nBytes << " bytes, "
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				      <<"wrote " << nBytesWritten << " bytes." << std::endl;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    char *ch = pbase();
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (int i = 0; i < nBytesWritten; i++) {
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      std::cout << (char) ch[i];
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    std::cout << std::endl;
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // end of debug.
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif
 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
 |