|
|
|
|
|
|
|
|
|
|
|
|
|
|
childStarted = false;
|
|
|
childStarted = false;
|
|
|
childExited = false;
|
|
|
childExited = false;
|
|
|
|
|
|
childExitedInferred = false;
|
|
|
exitCodeObtainedFlag = false;
|
|
|
exitCodeObtainedFlag = false;
|
|
|
exitCode = 0;
|
|
|
exitCode = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
bool Child::isRunning() const {
|
|
|
bool Child::isRunning() const {
|
|
|
return childStarted && !childExited;
|
|
|
|
|
|
|
|
|
return childStarted && !childExited && !childExitedInferred;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
bool Child::errorOccurred(std::string &errorDescription) const {
|
|
|
bool Child::errorOccurred(std::string &errorDescription) const {
|
|
|
|
|
|
|
|
|
&startInfo, // STARTUPINFO pointer
|
|
|
&startInfo, // STARTUPINFO pointer
|
|
|
&processInfo); // receives PROCESS_INFORMATION
|
|
|
&processInfo); // receives PROCESS_INFORMATION
|
|
|
|
|
|
|
|
|
// If an error occurs, exit the application.
|
|
|
|
|
|
|
|
|
// If an error occurs, throw.
|
|
|
if (!status ) {
|
|
|
if (!status ) {
|
|
|
throw std::runtime_error("Error from CreateProcess with "
|
|
|
throw std::runtime_error("Error from CreateProcess with "
|
|
|
"command line \"" + cmdline + "\": " +
|
|
|
"command line \"" + cmdline + "\": " +
|
|
|
|
|
|
|
|
|
nBytesRead = ::read(inputFileDescriptor,
|
|
|
nBytesRead = ::read(inputFileDescriptor,
|
|
|
bufferPtr,
|
|
|
bufferPtr,
|
|
|
bufferCapacity);
|
|
|
bufferCapacity);
|
|
|
|
|
|
|
|
|
if (-1 == nBytesRead) {
|
|
|
if (-1 == nBytesRead) {
|
|
|
|
|
|
|
|
|
if (stopReaderFlag) {
|
|
|
if (stopReaderFlag) {
|
|
|
|
|
|
|
|
|
} else if (0 == nBytesRead) {
|
|
|
} else if (0 == nBytesRead) {
|
|
|
|
|
|
|
|
|
// EOF; child exited.
|
|
|
// EOF; child exited.
|
|
|
|
|
|
childExitedInferred = true;
|
|
|
|
|
|
stopWriterFlag = true;
|
|
|
break;
|
|
|
break;
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Child::writeToChild() {
|
|
|
void Child::writeToChild() {
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
|
|
|
|
|
|
|
|
// Writing to a broken pipe raises SIGPIPE. Ignore that signal;
|
|
|
|
|
|
// the error is handled by the return value of ::write.
|
|
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
std::vector<char> localWriteBuffer(bufferCapacity);
|
|
|
std::vector<char> localWriteBuffer(bufferCapacity);
|
|
|
size_t nLocalWriteBytes;
|
|
|
size_t nLocalWriteBytes;
|
|
|
|
|
|
|