Read standard output and standard error of child process using stream_select. (#1253)

If a process filled up the buffer of the standard error pipe before closing the
standard output pipe, it would hang. As a result, the call to
stream_get_contents for the standard output pipe would not return, as the
standard error pipe needs to be read from in order for the process to continue.
This change uses stream_select to read from both pipes whenever data becomes
available.
This commit is contained in:
TobiasKappe 2017-01-06 10:18:14 +07:00 committed by Dmitry Khomutov
commit 5c10fca905
2 changed files with 53 additions and 5 deletions

View file

@ -62,6 +62,25 @@ class CommandExecutorTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($returnValue);
}
/**
* Runs a script that generates an output that fills the standard error
* buffer first, followed by the standard output buffer. The function
* should be able to read from both streams, thereby preventing the child
* process from blocking because one of its buffers is full.
*/
public function testExecuteCommand_AlternatesBothBuffers()
{
$length = 80000;
$script = <<<EOD
/bin/sh -c 'data="$(printf %%${length}s | tr " " "-")"; >&2 echo "\$data"; >&1 echo "\$data"'
EOD;
$data = str_repeat("-", $length);
$returnValue = $this->testedExecutor->executeCommand(array($script));
$this->assertTrue($returnValue);
$this->assertEquals($data, trim($this->testedExecutor->getLastOutput()));
$this->assertEquals($data, trim($this->testedExecutor->getLastError()));
}
public function testFindBinary_ReturnsPathInSpecifiedRoot()
{
$thisFileName = "CommandExecutorTest.php";