|
|
|
|
|
|
|
|
bool errorOccurred = false;
|
|
|
bool errorOccurred = false;
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
#ifdef _WIN32
|
|
|
if (!TerminateProcess(childProcess, terminateExitCode)) {
|
|
|
|
|
|
errorString += (errorOccurred ? "\n" : "");
|
|
|
|
|
|
errorString += "Error terminating the child process: " +
|
|
|
|
|
|
getErrorText();
|
|
|
|
|
|
errorOccurred = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
// Ignore errors. Reason: Terminating a proces that doesn't
|
|
|
|
|
|
// exist (e.g. has exited) gives an error.
|
|
|
|
|
|
(void) TerminateProcess(childProcess, terminateExitCode);
|
|
|
#else
|
|
|
#else
|
|
|
if (kill(childPid, SIGKILL) != 0) {
|
|
|
if (kill(childPid, SIGKILL) != 0) {
|
|
|
errorString += (errorOccurred ? "\n" : "");
|
|
|
errorString += (errorOccurred ? "\n" : "");
|
|
|
|
|
|
|
|
|
bool errorOccurred = false;
|
|
|
bool errorOccurred = false;
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
#ifdef _WIN32
|
|
|
if (!CloseHandle(inputHandle)) {
|
|
|
|
|
|
|
|
|
// Ignore errors. Reason: Terminating a proces that doesn't
|
|
|
|
|
|
// exist (e.g. has exited) gives an error.
|
|
|
|
|
|
(void) TerminateProcess(childProcess, terminateExitCode);
|
|
|
|
|
|
|
|
|
|
|
|
if (CloseHandle(inputHandle) == 0) {
|
|
|
errorString = "Error closing input from the child: " + getErrorText();
|
|
|
errorString = "Error closing input from the child: " + getErrorText();
|
|
|
errorOccurred = true;
|
|
|
errorOccurred = true;
|
|
|
}
|
|
|
}
|
|
|
if (!CloseHandle(outputHandle)) {
|
|
|
|
|
|
|
|
|
if (CloseHandle(outputHandle) == 0) {
|
|
|
errorString += (errorOccurred ? "\n" : "");
|
|
|
errorString += (errorOccurred ? "\n" : "");
|
|
|
errorString += "Error closing output to the child: " + getErrorText();
|
|
|
errorString += "Error closing output to the child: " + getErrorText();
|
|
|
errorOccurred = true;
|
|
|
errorOccurred = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if (!TerminateProcess(childProcess, terminateExitCode)) {
|
|
|
|
|
|
errorString += (errorOccurred ? "\n" : "");
|
|
|
|
|
|
errorString += "Error terminating the child process: " +
|
|
|
|
|
|
getErrorText();
|
|
|
|
|
|
errorOccurred = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
#else
|
|
|
if (0 != ::close(inputFileDescriptor)) {
|
|
|
if (0 != ::close(inputFileDescriptor)) {
|
|
|
errorString = "Error closing input from the child: " + getErrorText();
|
|
|
errorString = "Error closing input from the child: " + getErrorText();
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if (threadsAreRunning) {
|
|
|
if (threadsAreRunning) {
|
|
|
|
|
|
|
|
|
readerThread.join();
|
|
|
readerThread.join();
|
|
|
writerThread.join();
|
|
|
writerThread.join();
|
|
|
threadsAreRunning = false;
|
|
|
threadsAreRunning = false;
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// Reset.
|
|
|
// Reset.
|
|
|
|
|
|
|
|
|
break;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
errorText = "Error reading from the child process: ";
|
|
|
|
|
|
errorText += getErrorText();
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
// Broken pipe occurs when the child exits; this is not
|
|
|
|
|
|
// necessarily an error condition.
|
|
|
|
|
|
if (GetLastError() != ERROR_BROKEN_PIPE) {
|
|
|
|
|
|
|
|
|
|
|
|
errorText = "Error reading from the child process: ";
|
|
|
|
|
|
errorText += getErrorText();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
#else
|
|
|
#else
|