瀏覽代碼

ChildStream inherits from std::iostream.


git-svn-id: https://svn.microneil.com/svn/CodeDweller/branches/adeniz_1@77 d34b734f-a00e-4b39-a726-e4eeb87269ab
adeniz_1
adeniz 9 年之前
父節點
當前提交
669f79a111
共有 2 個檔案被更改,包括 41 行新增46 行删除
  1. 30
    30
      child.cpp
  2. 11
    16
      child.hpp

+ 30
- 30
child.cpp 查看文件

@@ -37,29 +37,29 @@
namespace CodeDweller {
Child::Child(std::vector<std::string> args, size_t bufSize) :
ChildStream::ChildStream(std::vector<std::string> args, size_t bufSize) :
childStreambuf(bufSize),
childStream(&childStreambuf),
std::iostream(&childStreambuf),
cmdArgs(args) {
init();
}
Child::Child(std::string childpath, size_t bufSize) :
ChildStream::ChildStream(std::string childpath, size_t bufSize) :
childStreambuf(bufSize),
childStream(&childStreambuf),
std::iostream(&childStreambuf),
cmdline(childpath) {
cmdArgs.push_back(childpath);
init();
}
Child::~Child() {
ChildStream::~ChildStream() {
// Close handles.
}
void
Child::init() {
ChildStream::init() {
if (cmdArgs.empty()) {
throw std::invalid_argument("A child executable must be specified.");
@@ -72,14 +72,14 @@ namespace CodeDweller {
}
size_t
Child::numBytesAvailable() const {
ChildStream::numBytesAvailable() const {
return childStreambuf.numBytesAvailable();
}
void
Child::run() {
ChildStream::run() {
if (childStarted) {
throw std::logic_error("Child process was active when "
@@ -246,7 +246,7 @@ namespace CodeDweller {
// Send message to parent.
errMsg = "Error redirecting stdin in the child: " + getErrorText();
write(childStdOutPipe[1], errMsg.data(), errMsg.size());
::write(childStdOutPipe[1], errMsg.data(), errMsg.size());
exit(-1);
}
@@ -256,7 +256,7 @@ namespace CodeDweller {
// Send message to parent.
errMsg = "Error redirecting stdout in the child: " + getErrorText();
write(childStdOutPipe[1], errMsg.data(), errMsg.size());
::write(childStdOutPipe[1], errMsg.data(), errMsg.size());
exit(-1);
}
@@ -269,7 +269,7 @@ namespace CodeDweller {
// Send message to parent.
errMsg = "Error closing the pipes in the child: " + getErrorText();
write(STDOUT_FILENO, errMsg.data(), errMsg.size());
::write(STDOUT_FILENO, errMsg.data(), errMsg.size());
exit(-1);
}
@@ -290,7 +290,7 @@ namespace CodeDweller {
// Send message to parent.
errMsg = "Error from exec: " + getErrorText();
write(STDOUT_FILENO, errMsg.data(), errMsg.size());
::write(STDOUT_FILENO, errMsg.data(), errMsg.size());
exit(-1);
}
@@ -318,7 +318,7 @@ namespace CodeDweller {
}
void
Child::terminate() {
ChildStream::terminate() {
if (isDone()) {
@@ -338,7 +338,7 @@ namespace CodeDweller {
}
bool
Child::isDone() {
ChildStream::isDone() {
if (childExited) {
@@ -400,7 +400,7 @@ namespace CodeDweller {
}
int32_t
Child::result() {
ChildStream::result() {
if (exitCodeObtainedFlag) {
@@ -428,7 +428,7 @@ namespace CodeDweller {
}
std::string
Child::getErrorText() {
ChildStream::getErrorText() {
#ifdef _WIN32
LPVOID winMsgBuf;
@@ -453,7 +453,7 @@ namespace CodeDweller {
#endif
}
Child::ChildStreambuf::ChildStreambuf(std::size_t bufferSize) :
ChildStream::ChildStreambuf::ChildStreambuf(std::size_t bufferSize) :
#ifdef _WIN32
inputHandle(0),
outputHandle(0),
@@ -480,14 +480,14 @@ namespace CodeDweller {
#ifdef _WIN32
void
Child::ChildStreambuf::setInputHandle(HANDLE inHandle) {
ChildStream::ChildStreambuf::setInputHandle(HANDLE inHandle) {
inputHandle = inHandle;
}
#else
void
Child::ChildStreambuf::setInputFileDescriptor(int inFd) {
ChildStream::ChildStreambuf::setInputFileDescriptor(int inFd) {
inputFileDescriptor = inFd;
@@ -495,7 +495,7 @@ namespace CodeDweller {
#endif
size_t
Child::ChildStreambuf::numBytesAvailable() const {
ChildStream::ChildStreambuf::numBytesAvailable() const {
size_t nBytesAvailable = egptr() - gptr();
@@ -538,7 +538,7 @@ namespace CodeDweller {
}
std::streambuf::int_type
Child::ChildStreambuf::underflow() {
ChildStream::ChildStreambuf::underflow() {
// Check for empty buffer.
if (gptr() < egptr()) {
@@ -574,9 +574,9 @@ namespace CodeDweller {
#else
ssize_t nBytesRead;
nBytesRead = read(inputFileDescriptor,
start,
readBuffer.size() - (start - base));
nBytesRead = ::read(inputFileDescriptor,
start,
readBuffer.size() - (start - base));
if (-1 == nBytesRead) {
return traits_type::eof();
}
@@ -596,14 +596,14 @@ namespace CodeDweller {
#ifdef _WIN32
void
Child::ChildStreambuf::setOutputHandle(HANDLE outHandle) {
ChildStream::ChildStreambuf::setOutputHandle(HANDLE outHandle) {
outputHandle = outHandle;
}
#else
void
Child::ChildStreambuf::setOutputFileDescriptor(int outFd) {
ChildStream::ChildStreambuf::setOutputFileDescriptor(int outFd) {
outputFileDescriptor = outFd;
@@ -611,7 +611,7 @@ namespace CodeDweller {
#endif
void
Child::ChildStreambuf::flushBuffer() {
ChildStream::ChildStreambuf::flushBuffer() {
// Write.
std::ptrdiff_t nBytes = pptr() - pbase();
@@ -632,7 +632,7 @@ namespace CodeDweller {
#else
ssize_t nBytesWritten;
nBytesWritten = write(outputFileDescriptor, pbase(), nBytes);
nBytesWritten = ::write(outputFileDescriptor, pbase(), nBytes);
#endif
@@ -649,7 +649,7 @@ namespace CodeDweller {
}
std::streambuf::int_type
Child::ChildStreambuf::overflow(int_type ch) {
ChildStream::ChildStreambuf::overflow(int_type ch) {
// Check whether we're writing EOF.
if (traits_type::eof() != ch) {
@@ -671,7 +671,7 @@ namespace CodeDweller {
}
int
Child::ChildStreambuf::sync() {
ChildStream::ChildStreambuf::sync() {
flushBuffer(); // Throws exception on failure.

+ 11
- 16
child.hpp 查看文件

@@ -48,7 +48,7 @@ namespace CodeDweller {

*/

/** Class that abstracts the creation of child processes.
/** Class that abstracts the communication with a child process.

This class provides functionality to create a child process,
communicate with the child process via streams and signals, and
@@ -56,7 +56,7 @@ namespace CodeDweller {

*/

class Child {
class ChildStream : public std::iostream {

private:

@@ -64,7 +64,7 @@ namespace CodeDweller {
/// writing to the standard input of the child process.
class ChildStreambuf : public std::streambuf {

friend class Child;
friend class ChildStream;

public:

@@ -180,11 +180,11 @@ namespace CodeDweller {
executable, and args[1] thru args[n] are the command-line
parameters.

\param[in] bufSize is the buffer size of the reader and writer
streams used to communicate with the child process.
\param[in] bufSize is the input and output buffer size of the
stream used to communicate with the child process.

*/
Child(std::vector<std::string> args, size_t bufSize = 4096);
ChildStream(std::vector<std::string> args, size_t bufSize = 4096);

/** Constructor for spawning without command-line parameters.

@@ -193,23 +193,18 @@ namespace CodeDweller {

\param[in] childpath contains the child executable file name.

\param[in] bufSize is the buffer size of the reader and writer
streams used to communicate with the child process.
\param[in] bufSize is the input and output buffer size of the
stream used to communicate with the child process.

*/
Child(std::string childpath, size_t bufSize = 4096);
ChildStream(std::string childpath, size_t bufSize = 4096);

/** Destructor terminates the child process. */
~Child();

/// I/O stream to read data from the child's standard output and
/// write data to the child's standard input.
std::iostream childStream;
~ChildStream();

/** Get the number of bytes available for input.

@returns number of bytes that can be read from reader without
blocking.
@returns number of bytes that can be read without blocking.

*/
size_t numBytesAvailable() const;

Loading…
取消
儲存