Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a891e14

Browse files
committed
[Process] Add Process::disableOutput and Process::enableOutput methods
1 parent c2d4be1 commit a891e14

File tree

5 files changed

+211
-3
lines changed

5 files changed

+211
-3
lines changed

src/Symfony/Component/Process/Process.php

+69-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class Process
5454
private $exitcode;
5555
private $fallbackExitcode;
5656
private $processInformation;
57+
private $outputDisabled = false;
5758
private $stdout;
5859
private $stderr;
5960
private $enhanceWindowsCompatibility;
@@ -193,6 +194,7 @@ public function __clone()
193194
* @return integer The exit status code
194195
*
195196
* @throws RuntimeException When process can't be launch or is stopped
197+
* @throws LogicException In case a callback is provided and output has been disabled
196198
*
197199
* @api
198200
*/
@@ -244,12 +246,16 @@ public function mustRun($callback = null)
244246
*
245247
* @throws RuntimeException When process can't be launch or is stopped
246248
* @throws RuntimeException When process is already running
249+
* @throws LogicException In case a callback is provided and output has been disabled
247250
*/
248251
public function start($callback = null)
249252
{
250253
if ($this->isRunning()) {
251254
throw new RuntimeException('Process is already running');
252255
}
256+
if ($this->outputDisabled && null !== $callback) {
257+
throw new LogicException('Output has been disabled, enable it to allow the use of a callback.');
258+
}
253259

254260
$this->resetProcessData();
255261
$this->starttime = $this->lastOutputTime = microtime(true);
@@ -400,15 +406,67 @@ public function signal($signal)
400406
return $this;
401407
}
402408

409+
/**
410+
* Disables fetching output and error output from the underlying process.
411+
*
412+
* @return Process
413+
*
414+
* @throws RuntimeException In case the process is already running
415+
*/
416+
public function disableOutput()
417+
{
418+
if ($this->isRunning()) {
419+
throw new RuntimeException('Disabling output while the process is running is not possible.');
420+
}
421+
422+
$this->outputDisabled = true;
423+
424+
return $this;
425+
}
426+
427+
/**
428+
* Enables fetching output and error output from the underlying process.
429+
*
430+
* @return Process
431+
*
432+
* @throws RuntimeException In case the process is already running
433+
*/
434+
public function enableOutput()
435+
{
436+
if ($this->isRunning()) {
437+
throw new RuntimeException('Enabling output while the process is running is not possible.');
438+
}
439+
440+
$this->outputDisabled = false;
441+
442+
return $this;
443+
}
444+
445+
/**
446+
* Returns true in case the output is disabled, false otherwise.
447+
*
448+
* @return Boolean
449+
*/
450+
public function isOutputDisabled()
451+
{
452+
return $this->outputDisabled;
453+
}
454+
403455
/**
404456
* Returns the current output of the process (STDOUT).
405457
*
406458
* @return string The process output
407459
*
460+
* @throws LogicException in case the output has been disabled.
461+
*
408462
* @api
409463
*/
410464
public function getOutput()
411465
{
466+
if ($this->outputDisabled) {
467+
throw new LogicException('Output has been disabled.');
468+
}
469+
412470
$this->readPipes(false, defined('PHP_WINDOWS_VERSION_BUILD') ? !$this->processInformation['running'] : true);
413471

414472
return $this->stdout;
@@ -420,6 +478,8 @@ public function getOutput()
420478
* In comparison with the getOutput method which always return the whole
421479
* output, this one returns the new output since the last call.
422480
*
481+
* @throws LogicException in case the output has been disabled.
482+
*
423483
* @return string The process output since the last call
424484
*/
425485
public function getIncrementalOutput()
@@ -450,10 +510,16 @@ public function clearOutput()
450510
*
451511
* @return string The process error output
452512
*
513+
* @throws LogicException in case the output has been disabled.
514+
*
453515
* @api
454516
*/
455517
public function getErrorOutput()
456518
{
519+
if ($this->outputDisabled) {
520+
throw new LogicException('Output has been disabled.');
521+
}
522+
457523
$this->readPipes(false, defined('PHP_WINDOWS_VERSION_BUILD') ? !$this->processInformation['running'] : true);
458524

459525
return $this->stderr;
@@ -466,6 +532,8 @@ public function getErrorOutput()
466532
* whole error output, this one returns the new error output since the last
467533
* call.
468534
*
535+
* @throws LogicException in case the output has been disabled.
536+
*
469537
* @return string The process error output since the last call
470538
*/
471539
public function getIncrementalErrorOutput()
@@ -1083,7 +1151,7 @@ public static function isPtySupported()
10831151
private function getDescriptors()
10841152
{
10851153
$this->processPipes = new ProcessPipes($this->useFileHandles, $this->tty, $this->pty);
1086-
$descriptors = $this->processPipes->getDescriptors();
1154+
$descriptors = $this->processPipes->getDescriptors($this->outputDisabled);
10871155

10881156
if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
10891157
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild

src/Symfony/Component/Process/ProcessBuilder.php

+32-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ProcessBuilder
2929
private $options = array();
3030
private $inheritEnv = true;
3131
private $prefix = array();
32+
private $outputDisabled = false;
3233

3334
public function __construct(array $arguments = array())
3435
{
@@ -154,6 +155,30 @@ public function setOption($name, $value)
154155
return $this;
155156
}
156157

158+
/**
159+
* Disables fetching output and error output from the underlying process.
160+
*
161+
* @return Process
162+
*/
163+
public function disableOutput()
164+
{
165+
$this->outputDisabled = true;
166+
167+
return $this;
168+
}
169+
170+
/**
171+
* Enables fetching output and error output from the underlying process.
172+
*
173+
* @return Process
174+
*/
175+
public function enableOutput()
176+
{
177+
$this->outputDisabled = false;
178+
179+
return $this;
180+
}
181+
157182
public function getProcess()
158183
{
159184
if (0 === count($this->prefix) && 0 === count($this->arguments)) {
@@ -172,6 +197,12 @@ public function getProcess()
172197
$env = $this->env;
173198
}
174199

175-
return new Process($script, $this->cwd, $env, $this->stdin, $this->timeout, $options);
200+
$process = new Process($script, $this->cwd, $env, $this->stdin, $this->timeout, $options);
201+
202+
if ($this->outputDisabled) {
203+
$process->disableOutput();
204+
}
205+
206+
return $process;
176207
}
177208
}

src/Symfony/Component/Process/ProcessPipes.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,22 @@ public function closeUnixPipes()
101101
/**
102102
* Returns an array of descriptors for the use of proc_open.
103103
*
104+
* @param Boolean $disableOutput Whether to redirect STDOUT and STDERR to /dev/null or not.
105+
*
104106
* @return array
105107
*/
106-
public function getDescriptors()
108+
public function getDescriptors($disableOutput)
107109
{
110+
if ($disableOutput) {
111+
$nullstream = fopen(defined('PHP_WINDOWS_VERSION_BUILD') ? 'NUL' : '/dev/null', 'c');
112+
113+
return array(
114+
array('pipe', 'r'),
115+
$nullstream,
116+
$nullstream,
117+
);
118+
}
119+
108120
if ($this->useFiles) {
109121
return array(
110122
array('pipe', 'r'),

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

+78
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,84 @@ public function testSignalWithWrongNonIntSignal()
700700
$process->signal('Céphalopodes');
701701
}
702702

703+
public function testDisableOutputDisablesTheOutput()
704+
{
705+
$p = $this->getProcess('php -r "usleep(500000);"');
706+
$this->assertFalse($p->isOutputDisabled());
707+
$p->disableOutput();
708+
$this->assertTrue($p->isOutputDisabled());
709+
$p->enableOutput();
710+
$this->assertFalse($p->isOutputDisabled());
711+
}
712+
713+
public function testDisableOutputWhileRunningThrowsException()
714+
{
715+
$p = $this->getProcess('php -r "usleep(500000);"');
716+
$p->start();
717+
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Disabling output while the process is running is not possible.');
718+
$p->disableOutput();
719+
}
720+
721+
public function testEnableOutputWhileRunningThrowsException()
722+
{
723+
$p = $this->getProcess('php -r "usleep(500000);"');
724+
$p->disableOutput();
725+
$p->start();
726+
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Enabling output while the process is running is not possible.');
727+
$p->enableOutput();
728+
}
729+
730+
public function testEnableOrDisableOutputAfterRunDoesNotThrowException()
731+
{
732+
$p = $this->getProcess('php -r "usleep(500000);"');
733+
$p->disableOutput();
734+
$p->start();
735+
$p->wait();
736+
$p->enableOutput();
737+
$p->disableOutput();
738+
}
739+
740+
/**
741+
* @dataProvider provideStartMethods
742+
*/
743+
public function testStartWithACallbackAndDisabledOutput($startMethod)
744+
{
745+
$p = $this->getProcess('php -r "usleep(500000);"');
746+
$p->disableOutput();
747+
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.');
748+
call_user_func(array($p, $startMethod), function () {});
749+
}
750+
751+
public function provideStartMethods()
752+
{
753+
return array(
754+
array('start'),
755+
array('run'),
756+
array('mustRun'),
757+
);
758+
}
759+
760+
/**
761+
* @dataProvider provideOutputFetchingMethods
762+
*/
763+
public function testGetOutputWhileDisabled($fetchMethod)
764+
{
765+
$p = $this->getProcess('php -r "usleep(500000);"');
766+
$p->disableOutput();
767+
$this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output has been disabled.');
768+
call_user_func(array($p, $fetchMethod));
769+
}
770+
771+
public function provideOutputFetchingMethods()
772+
{
773+
return array(
774+
array('getOutput'),
775+
array('getIncrementalOutput'),
776+
array('getErrorOutput'),
777+
array('getIncrementalErrorOutput'),
778+
);
779+
}
780+
703781
public function responsesCodeProvider()
704782
{
705783
return array(

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

+19
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,23 @@ public function testShouldNotThrowALogicExceptionIfNoPrefix()
193193
$this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
194194
}
195195
}
196+
197+
public function testShouldReturnProcessWithDisabledOutput()
198+
{
199+
$process = ProcessBuilder::create(array('/usr/bin/php'))
200+
->disableOutput()
201+
->getProcess();
202+
203+
$this->assertTrue($process->isOutputDisabled());
204+
}
205+
206+
public function testShouldReturnProcessWithEnabledOutput()
207+
{
208+
$process = ProcessBuilder::create(array('/usr/bin/php'))
209+
->disableOutput()
210+
->enableOutput()
211+
->getProcess();
212+
213+
$this->assertFalse($process->isOutputDisabled());
214+
}
196215
}

0 commit comments

Comments
 (0)