Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbd38abd

Browse files
[Process] Enhance compatiblity with --enable-sigchild
1 parented22696 commitbd38abd

File tree

8 files changed

+123
-706
lines changed

8 files changed

+123
-706
lines changed

‎.travis.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ addons:
1010
cache:
1111
directories:
1212
-.phpunit
13+
-php-5.3.9
1314

1415
matrix:
1516
include:
@@ -32,6 +33,7 @@ env:
3233

3334
before_install:
3435
-if [[ "$deps" = "no" ]] && [[ "$TRAVIS_PHP_VERSION" =~ 5.[45] ]] && [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then export deps=skip; fi;
36+
-if [[ $deps = no && $TRAVIS_PHP_VERSION = 5.3 && ! -d php-5.3.9/sapi ]]; then wget http://museum.php.net/php5/php-5.3.9.tar.bz2; tar -xjf php-5.3.9.tar.bz2; (cd php-5.3.9; ./configure --enable-sigchild --enable-pcntl; make -j2); fi;
3537
-if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi;
3638
-echo "memory_limit = -1" >> $INI_FILE
3739
-echo "session.gc_probability = 0" >> $INI_FILE
@@ -54,6 +56,7 @@ install:
5456
script:
5557
-if [ "$deps" = "no" ]; then echo "$COMPONENTS" | parallel --gnu '$PHPUNIT --exclude-group tty,benchmark,intl-data {}'; fi;
5658
-if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi;
59+
-if [[ $deps = no && $TRAVIS_PHP_VERSION = 5.3 ]]; then php-5.3.9/sapi/cli/php .phpunit/phpunit-4.8/phpunit src/Symfony/Component/Process/; fi;
5760
-if [ "$deps" = "high" ]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer --prefer-source update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi;
5861
-if [ "$deps" = "low" ]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi;
5962
-if [ "$deps" = "skip" ]; then echo 'This matrix line is skipped for pull requests.'; fi;

‎src/Symfony/Component/Process/Process.php‎

Lines changed: 57 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class Process
4646
private$timeout;
4747
private$options;
4848
private$exitcode;
49-
private$fallbackExitcode;
49+
private$fallbackStatus =array();
5050
private$processInformation;
5151
private$stdout;
5252
private$stderr;
@@ -65,6 +65,14 @@ class Process
6565
private$latestSignal;
6666

6767
privatestatic$sigchild;
68+
privatestatic$posixSignals =array(
69+
1 =>1,// SIGHUP
70+
2 =>2,// SIGINT
71+
3 =>3,// SIGQUIT
72+
6 =>6,// SIGABRT
73+
14 =>14,// SIGALRM
74+
15 =>15,// SIGTERM
75+
);
6876

6977
/**
7078
* Exit codes translation table.
@@ -339,17 +347,9 @@ public function wait($callback = null)
339347
* Returns the Pid (process identifier), if applicable.
340348
*
341349
* @return int|null The process id if running, null otherwise
342-
*
343-
* @throws RuntimeException In case --enable-sigchild is activated
344350
*/
345351
publicfunctiongetPid()
346352
{
347-
if ($this->isSigchildEnabled()) {
348-
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.');
349-
}
350-
351-
$this->updateStatus(false);
352-
353353
return$this->isRunning() ?$this->processInformation['pid'] :null;
354354
}
355355

@@ -361,7 +361,7 @@ public function getPid()
361361
* @return Process
362362
*
363363
* @throws LogicException In case the process is not running
364-
* @throws RuntimeException In case --enable-sigchild is activated
364+
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
365365
* @throws RuntimeException In case of failure
366366
*/
367367
publicfunctionsignal($signal)
@@ -467,7 +467,7 @@ public function getIncrementalErrorOutput()
467467
*/
468468
publicfunctiongetExitCode()
469469
{
470-
if ($this->isSigchildEnabled() &&!$this->enhanceSigchildCompatibility) {
470+
if (!$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
471471
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
472472
}
473473

@@ -484,8 +484,6 @@ public function getExitCode()
484484
*
485485
* @return null|string A string representation for the exit status code, null if the Process is not terminated.
486486
*
487-
* @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
488-
*
489487
* @see http://tldp.org/LDP/abs/html/exitcodes.html
490488
* @see http://en.wikipedia.org/wiki/Unix_signal
491489
*/
@@ -522,12 +520,10 @@ public function hasBeenSignaled()
522520
{
523521
$this->requireProcessIsTerminated(__FUNCTION__);
524522

525-
if ($this->isSigchildEnabled()) {
523+
if (!$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
526524
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
527525
}
528526

529-
$this->updateStatus(false);
530-
531527
return$this->processInformation['signaled'];
532528
}
533529

@@ -545,12 +541,10 @@ public function getTermSignal()
545541
{
546542
$this->requireProcessIsTerminated(__FUNCTION__);
547543

548-
if ($this->isSigchildEnabled()) {
544+
if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 ===$this->processInformation['termsig'])) {
549545
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
550546
}
551547

552-
$this->updateStatus(false);
553-
554548
return$this->processInformation['termsig'];
555549
}
556550

@@ -567,8 +561,6 @@ public function hasBeenStopped()
567561
{
568562
$this->requireProcessIsTerminated(__FUNCTION__);
569563

570-
$this->updateStatus(false);
571-
572564
return$this->processInformation['stopped'];
573565
}
574566

@@ -585,8 +577,6 @@ public function getStopSignal()
585577
{
586578
$this->requireProcessIsTerminated(__FUNCTION__);
587579

588-
$this->updateStatus(false);
589-
590580
return$this->processInformation['stopsig'];
591581
}
592582

@@ -660,7 +650,7 @@ public function stop($timeout = 10, $signal = null)
660650
usleep(1000);
661651
}while ($this->isRunning() &&microtime(true) <$timeoutMicro);
662652

663-
if ($this->isRunning() && !$this->isSigchildEnabled()) {
653+
if ($this->isRunning()) {
664654
// Avoid exception here: process is supposed to be running, but it might have stopped just
665655
// after this line. In any case, let's silently discard the error, we cannot do anything.
666656
$this->doSignal($signal ?:9,false);
@@ -998,9 +988,15 @@ private function getDescriptors()
998988

999989
if (!$this->useFileHandles &&$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
1000990
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
1001-
$descriptors =array_merge($descriptors,array(array('pipe','w')));
991+
$descriptors[3] =array('pipe','w');
992+
993+
$trap ='';
994+
foreach (self::$posixSignalsas$s) {
995+
$trap .="trap 'echo s$s >&3'$s;";
996+
}
1002997

1003-
$this->commandline ='('.$this->commandline.') 3>/dev/null; code=$?; echo $code >&3; exit $code';
998+
$this->commandline =$trap.'{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
999+
$this->commandline .='pid=$!; echo p$pid >&3; wait $pid; code=$?; echo x$code >&3; exit $code';
10041000
}
10051001

10061002
return$descriptors;
@@ -1047,10 +1043,13 @@ protected function updateStatus($blocking)
10471043
}
10481044

10491045
$this->processInformation =proc_get_status($this->process);
1050-
$this->captureExitCode();
10511046

10521047
$this->readPipes($blocking,'\\' ===DIRECTORY_SEPARATOR ? !$this->processInformation['running'] :true);
10531048

1049+
if ($this->fallbackStatus &&$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
1050+
$this->processInformation =$this->fallbackStatus +$this->processInformation;
1051+
}
1052+
10541053
if (!$this->processInformation['running']) {
10551054
$this->close();
10561055
}
@@ -1067,7 +1066,7 @@ protected function isSigchildEnabled()
10671066
returnself::$sigchild;
10681067
}
10691068

1070-
if (!function_exists('phpinfo')) {
1069+
if (!function_exists('phpinfo') ||defined('HHVM_VERSION')) {
10711070
returnself::$sigchild =false;
10721071
}
10731072

@@ -1093,24 +1092,24 @@ private function readPipes($blocking, $close)
10931092

10941093
$callback =$this->callback;
10951094
foreach ($resultas$type =>$data) {
1096-
if (3 ==$type) {
1097-
$this->fallbackExitcode = (int)$data;
1095+
if (3 ===$type) {
1096+
foreach (explode("\n",substr($data,0, -1))as$data) {
1097+
if ('p' ===$data[0]) {
1098+
$this->fallbackStatus['pid'] = (int)substr($data,1);
1099+
}elseif ('s' ===$data[0]) {
1100+
$this->fallbackStatus['signaled'] =true;
1101+
$this->fallbackStatus['exitcode'] = -1;
1102+
$this->fallbackStatus['termsig'] = (int)substr($data,1);
1103+
}elseif ('x' ===$data[0] && !isset($this->fallbackStatus['signaled'])) {
1104+
$this->fallbackStatus['exitcode'] = (int)substr($data,1);
1105+
}
1106+
}
10981107
}else {
10991108
$callback($type ===self::STDOUT ?self::OUT :self::ERR,$data);
11001109
}
11011110
}
11021111
}
11031112

1104-
/**
1105-
* Captures the exitcode if mentioned in the process information.
1106-
*/
1107-
privatefunctioncaptureExitCode()
1108-
{
1109-
if (isset($this->processInformation['exitcode']) && -1 !=$this->processInformation['exitcode']) {
1110-
$this->exitcode =$this->processInformation['exitcode'];
1111-
}
1112-
}
1113-
11141113
/**
11151114
* Closes process resource, closes file handles, sets the exitcode.
11161115
*
@@ -1120,19 +1119,19 @@ private function close()
11201119
{
11211120
$this->processPipes->close();
11221121
if (is_resource($this->process)) {
1123-
$exitcode =proc_close($this->process);
1124-
}else {
1125-
$exitcode = -1;
1122+
proc_close($this->process);
11261123
}
1127-
1128-
$this->exitcode = -1 !==$exitcode ?$exitcode : (null !==$this->exitcode ?$this->exitcode : -1);
1124+
$this->exitcode =$this->processInformation['exitcode'];
11291125
$this->status =self::STATUS_TERMINATED;
11301126

1131-
if (-1 ===$this->exitcode &&null !==$this->fallbackExitcode) {
1132-
$this->exitcode =$this->fallbackExitcode;
1133-
}elseif (-1 ===$this->exitcode &&$this->processInformation['signaled'] &&0 <$this->processInformation['termsig']) {
1134-
// if process has been signaled, no exitcode but a valid termsig, apply Unix convention
1135-
$this->exitcode =128 +$this->processInformation['termsig'];
1127+
if (-1 ===$this->exitcode) {
1128+
if ($this->processInformation['signaled'] &&0 <$this->processInformation['termsig']) {
1129+
// if process has been signaled, no exitcode but a valid termsig, apply Unix convention
1130+
$this->exitcode =128 +$this->processInformation['termsig'];
1131+
}elseif ($this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
1132+
$this->processInformation['signaled'] =true;
1133+
$this->processInformation['termsig'] = -1;
1134+
}
11361135
}
11371136

11381137
// Free memory from self-reference callback created by buildCallback
@@ -1151,7 +1150,7 @@ private function resetProcessData()
11511150
$this->starttime =null;
11521151
$this->callback =null;
11531152
$this->exitcode =null;
1154-
$this->fallbackExitcode =null;
1153+
$this->fallbackStatus =array();
11551154
$this->processInformation =null;
11561155
$this->stdout =null;
11571156
$this->stderr =null;
@@ -1171,7 +1170,7 @@ private function resetProcessData()
11711170
* @return bool True if the signal was sent successfully, false otherwise
11721171
*
11731172
* @throws LogicException In case the process is not running
1174-
* @throws RuntimeException In case --enable-sigchild is activated
1173+
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
11751174
* @throws RuntimeException In case of failure
11761175
*/
11771176
privatefunctiondoSignal($signal,$throwException)
@@ -1184,9 +1183,9 @@ private function doSignal($signal, $throwException)
11841183
returnfalse;
11851184
}
11861185

1187-
if ($this->isSigchildEnabled()) {
1186+
if ($this->enhanceSigchildCompatibility &&$this->isSigchildEnabled() && !isset(self::$posixSignals[$signal]) && !(function_exists('posix_kill') && @posix_kill($this->getPid(),$signal))) {
11881187
if ($throwException) {
1189-
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. The process can notbe signaled.');
1188+
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild and posix_kill() is notavailable.');
11901189
}
11911190

11921191
returnfalse;
@@ -1211,7 +1210,10 @@ private function doSignal($signal, $throwException)
12111210
returnfalse;
12121211
}
12131212

1214-
$this->latestSignal =$signal;
1213+
$this->latestSignal = (int)$signal;
1214+
$this->fallbackStatus['signaled'] =true;
1215+
$this->fallbackStatus['exitcode'] = -1;
1216+
$this->fallbackStatus['termsig'] =$this->latestSignal;
12151217

12161218
returntrue;
12171219
}

‎src/Symfony/Component/Process/Tests/PhpProcessTest.php‎

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,20 @@ public function testNonBlockingWorks()
3030

3131
publicfunctiontestCommandLine()
3232
{
33-
if ('phpdbg' ===PHP_SAPI) {
34-
$this->markTestSkipped('phpdbg SAPI is not supported by this test.');
35-
}
36-
3733
$process =newPhpProcess(<<<PHP
3834
<?php echo 'foobar';
3935
PHP
4036
);
4137

42-
$f =newPhpExecutableFinder();
43-
$commandLine =$f->find();
38+
$commandLine =$process->getCommandLine();
4439

45-
$this->assertSame($commandLine,$process->getCommandLine(),'::getCommandLine() returns the command line of PHP before start');
40+
$f =newPhpExecutableFinder();
41+
$this->assertContains($f->find(),$commandLine,'::getCommandLine() returns the command line of PHP before start');
4642

4743
$process->start();
48-
$this->assertSame($commandLine,$process->getCommandLine(),'::getCommandLine() returns the command line of PHP after start');
44+
$this->assertContains($commandLine,$process->getCommandLine(),'::getCommandLine() returns the command line of PHP after start');
4945

5046
$process->wait();
51-
$this->assertSame($commandLine,$process->getCommandLine(),'::getCommandLine() returns the command line of PHP after wait');
47+
$this->assertContains($commandLine,$process->getCommandLine(),'::getCommandLine() returns the command line of PHP after wait');
5248
}
5349
}

‎src/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php‎

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp