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

View File

@ -77,7 +77,8 @@ bool cmProcess::StartProcess()
int cmProcess::GetNextOutputLine(std::string& stdOutLine,
std::string& stdErrLine,
bool& gotStdOut,
bool& gotStdErr)
bool& gotStdErr,
bool running)
{
if(this->StdErrorBuffer.empty() && this->StdOutBuffer.empty())
{
@ -91,6 +92,27 @@ int cmProcess::GetNextOutputLine(std::string& stdOutLine,
this->StdOutBuffer.begin();
std::vector<char>::iterator erriter =
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.
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 false if there is no new data
void cmProcess::CheckOutput(double timeout)
bool cmProcess::CheckOutput(double timeout)
{
// Wait for data from the process.
int length;
@ -159,7 +181,7 @@ void cmProcess::CheckOutput(double timeout)
{
// Timeout has been exceeded.
this->LastOutputPipe = pipe;
return;
return true;
}
else if(pipe == cmsysProcess_Pipe_STDOUT)
{
@ -180,17 +202,17 @@ void cmProcess::CheckOutput(double timeout)
if(!this->StdOutBuffer.empty())
{
this->LastOutputPipe = cmsysProcess_Pipe_STDOUT;
return;
return false;
}
else if(!this->StdErrorBuffer.empty())
{
this->LastOutputPipe = cmsysProcess_Pipe_STDERR;
return;
return false;
}
else
{
this->LastOutputPipe = cmsysProcess_Pipe_None;
return;
return false;
}
}
}

View File

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