Skip to content

Commit 8cd9138

Browse files
bug #18023 [Process] getIncrementalOutput should work without calling getOutput (romainneutron)
This PR was merged into the 2.7 branch. Discussion ---------- [Process] getIncrementalOutput should work without calling getOutput | Q | A | ------------- | --- | Branch | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #17937 | License | MIT Commits ------- 37d8695 [Process] getIncrementalOutput should work without calling getOutput
2 parents bcb1b2d + 37d8695 commit 8cd9138

File tree

2 files changed

+47
-24
lines changed

2 files changed

+47
-24
lines changed

src/Symfony/Component/Process/Process.php

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,7 @@ public function isOutputDisabled()
462462
*/
463463
public function getOutput()
464464
{
465-
if ($this->outputDisabled) {
466-
throw new LogicException('Output has been disabled.');
467-
}
468-
469-
$this->requireProcessIsStarted(__FUNCTION__);
470-
471-
$this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
465+
$this->readPipesForOutput(__FUNCTION__);
472466

473467
if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
474468
return '';
@@ -490,11 +484,7 @@ public function getOutput()
490484
*/
491485
public function getIncrementalOutput()
492486
{
493-
if ($this->outputDisabled) {
494-
throw new LogicException('Output has been disabled.');
495-
}
496-
497-
$this->requireProcessIsStarted(__FUNCTION__);
487+
$this->readPipesForOutput(__FUNCTION__);
498488

499489
$latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
500490
$this->incrementalOutputOffset = ftell($this->stdout);
@@ -530,13 +520,7 @@ public function clearOutput()
530520
*/
531521
public function getErrorOutput()
532522
{
533-
if ($this->outputDisabled) {
534-
throw new LogicException('Output has been disabled.');
535-
}
536-
537-
$this->requireProcessIsStarted(__FUNCTION__);
538-
539-
$this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
523+
$this->readPipesForOutput(__FUNCTION__);
540524

541525
if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
542526
return '';
@@ -559,11 +543,7 @@ public function getErrorOutput()
559543
*/
560544
public function getIncrementalErrorOutput()
561545
{
562-
if ($this->outputDisabled) {
563-
throw new LogicException('Output has been disabled.');
564-
}
565-
566-
$this->requireProcessIsStarted(__FUNCTION__);
546+
$this->readPipesForOutput(__FUNCTION__);
567547

568548
$latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
569549
$this->incrementalErrorOutputOffset = ftell($this->stderr);
@@ -1328,6 +1308,24 @@ protected function isSigchildEnabled()
13281308
return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
13291309
}
13301310

1311+
/**
1312+
* Reads pipes for the freshest output.
1313+
*
1314+
* @param $caller The name of the method that needs fresh outputs
1315+
*
1316+
* @throw LogicException in case output has been disabled or process is not started
1317+
*/
1318+
private function readPipesForOutput($caller)
1319+
{
1320+
if ($this->outputDisabled) {
1321+
throw new LogicException('Output has been disabled.');
1322+
}
1323+
1324+
$this->requireProcessIsStarted($caller);
1325+
1326+
$this->updateStatus(false);
1327+
}
1328+
13311329
/**
13321330
* Validates and returns the filtered timeout.
13331331
*

src/Symfony/Component/Process/Tests/ProcessTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,31 @@ public function pipesCodeProvider()
11591159
return $codes;
11601160
}
11611161

1162+
/**
1163+
* @dataProvider provideVariousIncrementals
1164+
*/
1165+
public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method) {
1166+
$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);
1167+
$process->start();
1168+
$result = '';
1169+
$limit = microtime(true) + 3;
1170+
$expected = '012';
1171+
1172+
while ($result !== $expected && microtime(true) < $limit) {
1173+
$result .= $process->$method();
1174+
}
1175+
1176+
$this->assertSame($expected, $result);
1177+
$process->stop();
1178+
}
1179+
1180+
public function provideVariousIncrementals() {
1181+
return array(
1182+
array('php://stdout', 'getIncrementalOutput'),
1183+
array('php://stderr', 'getIncrementalErrorOutput'),
1184+
);
1185+
}
1186+
11621187
/**
11631188
* provides default method names for simple getter/setter.
11641189
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy