Browse Source

Ignore SIGPIPE in writer thread (*nix only). Reason:

Writing to a pipe with no reader raises a signal and returns
error.  The Child class handles the error returned.  Not ignoring
the signal would result in aborting the process.


git-svn-id: https://svn.microneil.com/svn/CodeDweller/branches/adeniz_1@115 d34b734f-a00e-4b39-a726-e4eeb87269ab
adeniz_1
adeniz 7 years ago
parent
commit
05f0fa5594
2 changed files with 20 additions and 4 deletions
  1. 14
    2
      child.cpp
  2. 6
    2
      child.hpp

+ 14
- 2
child.cpp View File

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;

+ 6
- 2
child.hpp View File

*/ */
template<typename T> template<typename T>
size_t writeAndShrink(T &data) { size_t writeAndShrink(T &data) {

if (!isRunning()) { if (!isRunning()) {
throw std::logic_error("No child process is running."); throw std::logic_error("No child process is running.");
} }
std::copy(data.begin(), std::copy(data.begin(),
data.begin() + nBytesToCopy, data.begin() + nBytesToCopy,
&(writeBuffer[nWriteBytes])); &(writeBuffer[nWriteBytes]));

nWriteBytes += nBytesToCopy; nWriteBytes += nBytesToCopy;


data.erase(data.begin(), data.begin() + nBytesToCopy); data.erase(data.begin(), data.begin() + nBytesToCopy);
/// True if the child process was successfully started. /// True if the child process was successfully started.
bool childStarted; bool childStarted;


/// True if the child process has exited.
/// True if a system call indicates that the child process has
/// exited.
bool childExited; bool childExited;


/// True if the child exited for any other reason.
bool childExitedInferred;

/// Child executable path and command-line parameters. /// Child executable path and command-line parameters.
std::vector<std::string> cmdArgs; std::vector<std::string> cmdArgs;



Loading…
Cancel
Save