diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 32704df3f1769..11ee3a938554c 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -463,13 +463,7 @@ public function isOutputDisabled() */ public function getOutput() { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); - - $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); + $this->readPipesForOutput(__FUNCTION__); if (false === $ret = stream_get_contents($this->stdout, -1, 0)) { return ''; @@ -491,11 +485,7 @@ public function getOutput() */ public function getIncrementalOutput() { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); + $this->readPipesForOutput(__FUNCTION__); $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); $this->incrementalOutputOffset = ftell($this->stdout); @@ -531,13 +521,7 @@ public function clearOutput() */ public function getErrorOutput() { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); - - $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); + $this->readPipesForOutput(__FUNCTION__); if (false === $ret = stream_get_contents($this->stderr, -1, 0)) { return ''; @@ -560,11 +544,7 @@ public function getErrorOutput() */ public function getIncrementalErrorOutput() { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); + $this->readPipesForOutput(__FUNCTION__); $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); $this->incrementalErrorOutputOffset = ftell($this->stderr); @@ -1328,6 +1308,24 @@ protected function isSigchildEnabled() return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); } + /** + * Reads pipes for the freshest output. + * + * @param $caller The name of the method that needs fresh outputs + * + * @throw LogicException in case output has been disabled or process is not started + */ + private function readPipesForOutput($caller) + { + if ($this->outputDisabled) { + throw new LogicException('Output has been disabled.'); + } + + $this->requireProcessIsStarted($caller); + + $this->updateStatus(false); + } + /** * Validates and returns the filtered timeout. * diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index 652246267cc0c..e06cb994c4c6d 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -1165,6 +1165,31 @@ public function pipesCodeProvider() return $codes; } + /** + * @dataProvider provideVariousIncrementals + */ + public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method) { + $process = new Process(self::$phpBin.' -r '.escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }'), null, null, null, null); + $process->start(); + $result = ''; + $limit = microtime(true) + 3; + $expected = '012'; + + while ($result !== $expected && microtime(true) < $limit) { + $result .= $process->$method(); + } + + $this->assertSame($expected, $result); + $process->stop(); + } + + public function provideVariousIncrementals() { + return array( + array('php://stdout', 'getIncrementalOutput'), + array('php://stderr', 'getIncrementalErrorOutput'), + ); + } + /** * provides default method names for simple getter/setter. */
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: