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 8 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

@@ -848,6 +848,7 @@ namespace CodeDweller {
childStarted = false;
childExited = false;
childExitedInferred = false;
exitCodeObtainedFlag = false;
exitCode = 0;
@@ -1021,7 +1022,7 @@ namespace CodeDweller {
}
bool Child::isRunning() const {
return childStarted && !childExited;
return childStarted && !childExited && !childExitedInferred;
}
bool Child::errorOccurred(std::string &errorDescription) const {
@@ -1137,7 +1138,7 @@ namespace CodeDweller {
&startInfo, // STARTUPINFO pointer
&processInfo); // receives PROCESS_INFORMATION
// If an error occurs, exit the application.
// If an error occurs, throw.
if (!status ) {
throw std::runtime_error("Error from CreateProcess with "
"command line \"" + cmdline + "\": " +
@@ -1484,6 +1485,7 @@ namespace CodeDweller {
nBytesRead = ::read(inputFileDescriptor,
bufferPtr,
bufferCapacity);
if (-1 == nBytesRead) {
if (stopReaderFlag) {
@@ -1497,6 +1499,8 @@ namespace CodeDweller {
} else if (0 == nBytesRead) {
// EOF; child exited.
childExitedInferred = true;
stopWriterFlag = true;
break;
}
@@ -1539,6 +1543,14 @@ namespace CodeDweller {
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);
size_t nLocalWriteBytes;

+ 6
- 2
child.hpp View File

@@ -910,7 +910,6 @@ namespace CodeDweller {
*/
template<typename T>
size_t writeAndShrink(T &data) {

if (!isRunning()) {
throw std::logic_error("No child process is running.");
}
@@ -934,6 +933,7 @@ namespace CodeDweller {
std::copy(data.begin(),
data.begin() + nBytesToCopy,
&(writeBuffer[nWriteBytes]));

nWriteBytes += nBytesToCopy;

data.erase(data.begin(), data.begin() + nBytesToCopy);
@@ -1307,9 +1307,13 @@ namespace CodeDweller {
/// True if the child process was successfully started.
bool childStarted;

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

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

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


Loading…
Cancel
Save