Permalink
Browse files

feature #23380 [Process] Remove enhanced sigchild compatibility (maid…

…maid)

This PR was merged into the 4.0-dev branch.

Discussion
----------

[Process] Remove enhanced sigchild compatibility

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #23376 (comment), #22836 (comment)
| License       | MIT
| Doc PR        | /

In 4.0, enhanced sigchild compatibility is always enabled.

Commits
-------

1aa7d68 Remove enhance sigchild compatibility
  • Loading branch information...
nicolas-grekas committed Jul 12, 2017
2 parents a55cbf8 + 1aa7d68 commit 1041f82ce2552bbbd8f9725bc95774e0025395d8
Showing with 11 additions and 123 deletions.
  1. +1 −1 .travis.yml
  2. +6 −60 src/Symfony/Component/Process/Process.php
  3. +4 −62 src/Symfony/Component/Process/Tests/ProcessTest.php
View
@@ -158,7 +158,7 @@ install:
echo "$COMPONENTS" | parallel --gnu "tfold {} $PHPUNIT_X {}"
tfold tty-group $PHPUNIT --group tty
if [[ $PHP = $MIN_PHP ]]; then
echo -e "1\\n0" | xargs -I{} bash -c "tfold src/Symfony/Component/Process.sigchild{} SYMFONY_DEPRECATIONS_HELPER=weak ENHANCE_SIGCHLD={} php-$MIN_PHP/sapi/cli/php ./phpunit --colors=always src/Symfony/Component/Process/"
tfold src/Symfony/Component/Process.sigchild SYMFONY_DEPRECATIONS_HELPER=weak php-$MIN_PHP/sapi/cli/php ./phpunit --colors=always src/Symfony/Component/Process/
fi
fi
}
@@ -64,7 +64,6 @@ class Process implements \IteratorAggregate
private $outputDisabled = false;
private $stdout;
private $stderr;
private $enhanceSigchildCompatibility;
private $process;
private $status = self::STATUS_READY;
private $incrementalOutputOffset = 0;
@@ -165,7 +164,6 @@ public function __construct($commandline, $cwd = null, array $env = null, $input
$this->setTimeout($timeout);
$this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
$this->pty = false;
$this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
}
public function __destruct()
@@ -218,17 +216,12 @@ public function run($callback = null, array $env = array())
*
* @return self
*
* @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled
* @throws ProcessFailedException if the process didn't terminate successfully
*
* @final since version 3.3
*/
public function mustRun(callable $callback = null, array $env = array())
{
if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
}
if (0 !== $this->run($callback, $env)) {
throw new ProcessFailedException($this);
}
@@ -297,7 +290,7 @@ public function start(callable $callback = null, array $env = array())
if ('\\' === DIRECTORY_SEPARATOR) {
$options['bypass_shell'] = true;
$commandline = $this->prepareWindowsCommandLine($commandline, $envBackup, $env);
} elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
} elseif (!$this->useFileHandles && $this->isSigchildEnabled()) {
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
$descriptors[3] = array('pipe', 'w');
@@ -665,15 +658,9 @@ public function clearErrorOutput()
* Returns the exit code returned by the process.
*
* @return null|int The exit status code, null if the Process is not terminated
*
* @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
*/
public function getExitCode()
{
if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
}
$this->updateStatus(false);
return $this->exitcode;
@@ -716,17 +703,12 @@ public function isSuccessful()
*
* @return bool
*
* @throws RuntimeException In case --enable-sigchild is activated
* @throws LogicException In case the process is not terminated
* @throws LogicException In case the process is not terminated
*/
public function hasBeenSignaled()
{
$this->requireProcessIsTerminated(__FUNCTION__);
if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
}
return $this->processInformation['signaled'];
}
@@ -744,7 +726,7 @@ public function getTermSignal()
{
$this->requireProcessIsTerminated(__FUNCTION__);
if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) {
if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) {
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
}
@@ -1153,42 +1135,6 @@ public function setInput($input)
return $this;
}
/**
* Returns whether sigchild compatibility mode is activated or not.
*
* @return bool
*
* @deprecated since version 3.3, to be removed in 4.0. Sigchild compatibility will always be enabled.
*/
public function getEnhanceSigchildCompatibility()
{
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
return $this->enhanceSigchildCompatibility;
}
/**
* Activates sigchild compatibility mode.
*
* Sigchild compatibility mode is required to get the exit code and
* determine the success of a process when PHP has been compiled with
* the --enable-sigchild option
*
* @param bool $enhance
*
* @return self The current Process instance
*
* @deprecated since version 3.3, to be removed in 4.0.
*/
public function setEnhanceSigchildCompatibility($enhance)
{
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
$this->enhanceSigchildCompatibility = (bool) $enhance;
return $this;
}
/**
* Sets whether environment variables will be inherited or not.
*
@@ -1322,7 +1268,7 @@ protected function updateStatus($blocking)
$this->readPipes($running && $blocking, '\\' !== DIRECTORY_SEPARATOR || !$running);
if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
if ($this->fallbackStatus && $this->isSigchildEnabled()) {
$this->processInformation = $this->fallbackStatus + $this->processInformation;
}
@@ -1431,7 +1377,7 @@ private function close()
if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
// if process has been signaled, no exitcode but a valid termsig, apply Unix convention
$this->exitcode = 128 + $this->processInformation['termsig'];
} elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
} elseif ($this->isSigchildEnabled()) {
$this->processInformation['signaled'] = true;
$this->processInformation['termsig'] = -1;
}
@@ -1496,7 +1442,7 @@ private function doSignal($signal, $throwException)
return false;
}
} else {
if (!$this->enhanceSigchildCompatibility || !$this->isSigchildEnabled()) {
if (!$this->isSigchildEnabled()) {
$ok = @proc_terminate($this->process, $signal);
} elseif (function_exists('posix_kill')) {
$ok = @posix_kill($pid, $signal);
@@ -28,7 +28,6 @@ class ProcessTest extends TestCase
private static $phpBin;
private static $process;
private static $sigchild;
private static $notEnhancedSigchild = false;
public static function setUpBeforeClass()
{
@@ -420,7 +419,6 @@ public function testExitCodeCommandFailed()
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX exit code');
}
$this->skipIfNotEnhancedSigchild();
// such command run in bash return an exitcode 127
$process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis');
@@ -455,7 +453,6 @@ public function testTTYCommandExitCode()
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does have /dev/tty support');
}
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo "foo" >> /dev/null');
$process->setTty(true);
@@ -481,8 +478,6 @@ public function testTTYInWindowsEnvironment()
public function testExitCodeTextIsNullWhenExitCodeIsNull()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('');
$this->assertNull($process->getExitCodeText());
}
@@ -503,8 +498,6 @@ public function testPTYCommand()
public function testMustRun()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo foo');
$this->assertSame($process, $process->mustRun());
@@ -513,8 +506,6 @@ public function testMustRun()
public function testSuccessfulMustRunHasCorrectExitCode()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo foo')->mustRun();
$this->assertEquals(0, $process->getExitCode());
}
@@ -524,16 +515,12 @@ public function testSuccessfulMustRunHasCorrectExitCode()
*/
public function testMustRunThrowsException()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('exit 1');
$process->mustRun();
}
public function testExitCodeText()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('');
$r = new \ReflectionObject($process);
$p = $r->getProperty('exitcode');
@@ -562,8 +549,6 @@ public function testUpdateStatus()
public function testGetExitCodeIsNullOnStart()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcessForCode('usleep(100000);');
$this->assertNull($process->getExitCode());
$process->start();
@@ -574,8 +559,6 @@ public function testGetExitCodeIsNullOnStart()
public function testGetExitCodeIsNullOnWhenStartingAgain()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcessForCode('usleep(100000);');
$process->run();
$this->assertEquals(0, $process->getExitCode());
@@ -587,8 +570,6 @@ public function testGetExitCodeIsNullOnWhenStartingAgain()
public function testGetExitCode()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo foo');
$process->run();
$this->assertSame(0, $process->getExitCode());
@@ -624,17 +605,13 @@ public function testStop()
public function testIsSuccessful()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo foo');
$process->run();
$this->assertTrue($process->isSuccessful());
}
public function testIsSuccessfulOnlyAfterTerminated()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcessForCode('usleep(100000);');
$process->start();
@@ -647,8 +624,6 @@ public function testIsSuccessfulOnlyAfterTerminated()
public function testIsNotSuccessful()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcessForCode('throw new \Exception(\'BOUM\');');
$process->run();
$this->assertFalse($process->isSuccessful());
@@ -659,7 +634,6 @@ public function testProcessIsNotSignaled()
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX signals');
}
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo foo');
$process->run();
@@ -671,7 +645,6 @@ public function testProcessWithoutTermSignal()
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX signals');
}
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('echo foo');
$process->run();
@@ -683,7 +656,6 @@ public function testProcessIsSignaledIfStopped()
if ('\\' === DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support POSIX signals');
}
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcessForCode('sleep(32);');
$process->start();
@@ -701,7 +673,10 @@ public function testProcessThrowsExceptionWhenExternallySignaled()
if (!function_exists('posix_kill')) {
$this->markTestSkipped('Function posix_kill is required.');
}
$this->skipIfNotEnhancedSigchild(false);
if (self::$sigchild) {
$this->markTestSkipped('PHP is compiled with --enable-sigchild.');
}
$process = $this->getProcessForCode('sleep(32.1);');
$process->start();
@@ -912,8 +887,6 @@ public function testSignal()
*/
public function testExitCodeIsAvailableAfterSignal()
{
$this->skipIfNotEnhancedSigchild();
$process = $this->getProcess('sleep 4');
$process->start();
$process->signal(SIGKILL);
@@ -1487,21 +1460,6 @@ private function getProcess($commandline, $cwd = null, array $env = null, $input
$process = new Process($commandline, $cwd, $env, $input, $timeout);
$process->inheritEnvironmentVariables();
if (false !== $enhance = getenv('ENHANCE_SIGCHLD')) {
try {
$process->setEnhanceSigchildCompatibility(false);
$process->getExitCode();
$this->fail('ENHANCE_SIGCHLD must be used together with a sigchild-enabled PHP.');
} catch (RuntimeException $e) {
$this->assertSame('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.', $e->getMessage());
if ($enhance) {
$process->setEnhanceSigchildCompatibility(true);
} else {
self::$notEnhancedSigchild = true;
}
}
}
if (self::$process) {
self::$process->stop(0);
}
@@ -1516,22 +1474,6 @@ private function getProcessForCode($code, $cwd = null, array $env = null, $input
{
return $this->getProcess(array(self::$phpBin, '-r', $code), $cwd, $env, $input, $timeout);
}
private function skipIfNotEnhancedSigchild($expectException = true)
{
if (self::$sigchild) {
if (!$expectException) {
$this->markTestSkipped('PHP is compiled with --enable-sigchild.');
} elseif (self::$notEnhancedSigchild) {
if (method_exists($this, 'expectException')) {
$this->expectException('Symfony\Component\Process\Exception\RuntimeException');
$this->expectExceptionMessage('This PHP has been compiled with --enable-sigchild.');
} else {
$this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild.');
}
}
}
}
}
class NonStringifiable

0 comments on commit 1041f82

Please sign in to comment.