diff --git a/src/Symfony/Component/Process/ProcessPipes.php b/src/Symfony/Component/Process/ProcessPipes.php index c35d7bc96b..67b11e615b 100644 --- a/src/Symfony/Component/Process/ProcessPipes.php +++ b/src/Symfony/Component/Process/ProcessPipes.php @@ -289,9 +289,13 @@ class ProcessPipes foreach ($r as $pipe) { $type = array_search($pipe, $this->pipes); - $data = fread($pipe, 8192); - if (strlen($data) > 0) { + $data = ''; + while ($dataread = fread($pipe, 8192)) { + $data .= $dataread; + } + + if ($data) { $read[$type] = $data; } diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index b5b34b2197..6401ec33e4 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -80,6 +80,32 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertLessThan(1.8, $duration); } + public function testAllOutputIsActuallyReadOnTermination() + { + // this code will result in a maximum of 2 reads of 8192 bytes by calling + // start() and isRunning(). by the time getOutput() is called the process + // has terminated so the internal pipes array is already empty. normally + // the call to start() will not read any data as the process will not have + // generated output, but this is non-deterministic so we must count it as + // a possibility. therefore we need 2 * 8192 plus another byte which will + // never be read. + $expectedOutputSize = 16385; + + $code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize); + $p = $this->getProcess(sprintf('php -r %s', escapeshellarg($code))); + + $p->start(); + usleep(250000); + + if ($p->isRunning()) { + $this->fail('Process execution did not complete in the required time frame'); + } + + $o = $p->getOutput(); + + $this->assertEquals($expectedOutputSize, strlen($o)); + } + public function testCallbacksAreExecutedWithStart() { $data = '';