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:
parent
9f1c7bdbaa
commit
07665de038
|
@ -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. */
|
||||||
|
|
Loading…
Reference in New Issue