BUG: Fixed issue where ctest would hang if a process terminated with output in its buffers but no newline

This commit is contained in:
Zach Mullen 2009-09-08 10:16:16 -04:00
parent 384f4d1f3f
commit a02ef56401
3 changed files with 39 additions and 12 deletions

View File

@ -38,18 +38,19 @@ bool cmCTestRunTest::IsRunning()
void cmCTestRunTest::CheckOutput() void cmCTestRunTest::CheckOutput()
{ {
std::string out, err; std::string out, err;
this->TestProcess->CheckOutput(.1); bool running = this->TestProcess->CheckOutput(.1);
//start our timeout for reading the process output //start our timeout for reading the process output
double clock_start = cmSystemTools::GetTime(); double clock_start = cmSystemTools::GetTime();
int pipe; int pipe;
bool gotStdOut = false; bool gotStdOut = false;
bool gotStdErr = false; bool gotStdErr = false;
while((pipe = this->TestProcess-> while((pipe = this->TestProcess->
GetNextOutputLine(out, err, gotStdOut, gotStdErr) ) GetNextOutputLine(out, err, gotStdOut, gotStdErr, running) )
!= cmsysProcess_Pipe_Timeout) != cmsysProcess_Pipe_Timeout)
{ {
if(pipe == cmsysProcess_Pipe_STDOUT || if(pipe == cmsysProcess_Pipe_STDOUT ||
pipe == cmsysProcess_Pipe_STDERR) pipe == cmsysProcess_Pipe_STDERR ||
pipe == cmsysProcess_Pipe_None)
{ {
if(gotStdErr) if(gotStdErr)
{ {
@ -65,6 +66,10 @@ void cmCTestRunTest::CheckOutput()
this->ProcessOutput += out; this->ProcessOutput += out;
this->ProcessOutput += "\n"; this->ProcessOutput += "\n";
} }
if(pipe == cmsysProcess_Pipe_None)
{
break;
}
} }
gotStdOut = false; gotStdOut = false;
gotStdErr = false; gotStdErr = false;

View File

@ -77,7 +77,8 @@ bool cmProcess::StartProcess()
int cmProcess::GetNextOutputLine(std::string& stdOutLine, int cmProcess::GetNextOutputLine(std::string& stdOutLine,
std::string& stdErrLine, std::string& stdErrLine,
bool& gotStdOut, bool& gotStdOut,
bool& gotStdErr) bool& gotStdErr,
bool running)
{ {
if(this->StdErrorBuffer.empty() && this->StdOutBuffer.empty()) if(this->StdErrorBuffer.empty() && this->StdOutBuffer.empty())
{ {
@ -91,6 +92,27 @@ int cmProcess::GetNextOutputLine(std::string& stdOutLine,
this->StdOutBuffer.begin(); this->StdOutBuffer.begin();
std::vector<char>::iterator erriter = std::vector<char>::iterator erriter =
this->StdErrorBuffer.begin(); this->StdErrorBuffer.begin();
//If process terminated, flush the buffer
if(!running)
{
if(!this->StdErrorBuffer.empty())
{
gotStdErr = true;
stdErrLine.append(&this->StdErrorBuffer[0], this->StdErrorBuffer.size());
this->StdErrorBuffer.erase(this->StdErrorBuffer.begin(),
this->StdErrorBuffer.end());
}
if(!this->StdOutBuffer.empty())
{
gotStdOut = true;
stdOutLine.append(&this->StdOutBuffer[0], this->StdOutBuffer.size());
this->StdOutBuffer.erase(this->StdOutBuffer.begin(),
this->StdOutBuffer.end());
}
return cmsysProcess_Pipe_None;
}
// Check for a newline in stdout. // Check for a newline in stdout.
for(;outiter != this->StdOutBuffer.end(); ++outiter) for(;outiter != this->StdOutBuffer.end(); ++outiter)
{ {
@ -145,7 +167,7 @@ int cmProcess::GetNextOutputLine(std::string& stdOutLine,
} }
// return true if there is a new line of data // return true if there is a new line of data
// return false if there is no new data // return false if there is no new data
void cmProcess::CheckOutput(double timeout) bool cmProcess::CheckOutput(double timeout)
{ {
// Wait for data from the process. // Wait for data from the process.
int length; int length;
@ -159,7 +181,7 @@ void cmProcess::CheckOutput(double timeout)
{ {
// Timeout has been exceeded. // Timeout has been exceeded.
this->LastOutputPipe = pipe; this->LastOutputPipe = pipe;
return; return true;
} }
else if(pipe == cmsysProcess_Pipe_STDOUT) else if(pipe == cmsysProcess_Pipe_STDOUT)
{ {
@ -180,17 +202,17 @@ void cmProcess::CheckOutput(double timeout)
if(!this->StdOutBuffer.empty()) if(!this->StdOutBuffer.empty())
{ {
this->LastOutputPipe = cmsysProcess_Pipe_STDOUT; this->LastOutputPipe = cmsysProcess_Pipe_STDOUT;
return; return false;
} }
else if(!this->StdErrorBuffer.empty()) else if(!this->StdErrorBuffer.empty())
{ {
this->LastOutputPipe = cmsysProcess_Pipe_STDERR; this->LastOutputPipe = cmsysProcess_Pipe_STDERR;
return; return false;
} }
else else
{ {
this->LastOutputPipe = cmsysProcess_Pipe_None; this->LastOutputPipe = cmsysProcess_Pipe_None;
return; return false;
} }
} }
} }

View File

@ -40,8 +40,8 @@ public:
// Return true if the process starts // Return true if the process starts
bool StartProcess(); bool StartProcess();
// return process state // return false if process has exited, true otherwise
void CheckOutput(double timeout); bool CheckOutput(double timeout);
// return the process status // return the process status
int GetProcessStatus(); int GetProcessStatus();
// return true if the process is running // return true if the process is running
@ -53,7 +53,7 @@ public:
int GetExitValue() { return this->ExitValue;} int GetExitValue() { return this->ExitValue;}
double GetTotalTime() { return this->TotalTime;} double GetTotalTime() { return this->TotalTime;}
int GetNextOutputLine(std::string& stdOutLine, std::string& stdErrLine, int GetNextOutputLine(std::string& stdOutLine, std::string& stdErrLine,
bool& gotStdOut, bool& gotStdErr); bool& gotStdOut, bool& gotStdErr, bool running);
private: private:
int LastOutputPipe; int LastOutputPipe;
double Timeout; double Timeout;