BUG: Handle case when select() lies

According to "man select" on Linux it is possible that select() lies
about data being ready on a pipe in some subtle cases.  We deal with
this by switching to non-blocking i/o and checking for EAGAIN.  See
issue #7180.
This commit is contained in:
Brad King 2008-08-20 09:57:09 -04:00
parent 9f1c7bdbaa
commit 07665de038
1 changed files with 10 additions and 7 deletions

View File

@ -770,14 +770,14 @@ void kwsysProcess_Execute(kwsysProcess* cp)
return; return;
} }
#if !KWSYSPE_USE_SELECT /* Set to non-blocking in case select lies, or for the polling
implementation. */
if(!kwsysProcessSetNonBlocking(p[0])) if(!kwsysProcessSetNonBlocking(p[0]))
{ {
kwsysProcessCleanup(cp, 1); kwsysProcessCleanup(cp, 1);
kwsysProcessCleanupDescriptor(&si.StdErr); kwsysProcessCleanupDescriptor(&si.StdErr);
return; return;
} }
#endif
} }
/* Replace the stderr pipe with a file if requested. In this case /* Replace the stderr pipe with a file if requested. In this case
@ -830,14 +830,12 @@ void kwsysProcess_Execute(kwsysProcess* cp)
failed = 1; failed = 1;
} }
#if !KWSYSPE_USE_SELECT /* Set the output pipe of the last process to be non-blocking in
/* Set the output pipe of the last process to be non-blocking so case select lies, or for the polling implementation. */
we can poll it. */ if(i == (cp->NumberOfCommands-1) && !kwsysProcessSetNonBlocking(readEnd))
if(i == cp->NumberOfCommands-1 && !kwsysProcessSetNonBlocking(readEnd))
{ {
failed = 1; failed = 1;
} }
#endif
if(failed) if(failed)
{ {
@ -1057,6 +1055,11 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
return 1; return 1;
} }
} }
else if(n < 0 && errno == EAGAIN)
{
/* No data are really ready. The select call lied. See the
"man select" page on Linux for cases when this occurs. */
}
else else
{ {
/* We are done reading from this pipe. */ /* We are done reading from this pipe. */