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

Commite7cc4aa

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

File tree

8 files changed

+184
-706
lines changed

8 files changed

+184
-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 echo -e "1\\n0" | parallel --gnu 'echo -e "\\nPHP --enable-sigchild enhanced={}" && ENHANCE_SIGCHLD={} php-5.3.9/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always 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: 63 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,9 @@ public function getIncrementalErrorOutput()
467467
*/
468468
publicfunctiongetExitCode()
469469
{
470-
if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {
470+
if (!$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
471+
$this->stop(0);
472+
471473
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
472474
}
473475

@@ -484,8 +486,6 @@ public function getExitCode()
484486
*
485487
* @return null|string A string representation for the exit status code, null if the Process is not terminated.
486488
*
487-
* @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
488-
*
489489
* @see http://tldp.org/LDP/abs/html/exitcodes.html
490490
* @see http://en.wikipedia.org/wiki/Unix_signal
491491
*/
@@ -522,12 +522,12 @@ public function hasBeenSignaled()
522522
{
523523
$this->requireProcessIsTerminated(__FUNCTION__);
524524

525-
if ($this->isSigchildEnabled()) {
525+
if (!$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
526+
$this->stop(0);
527+
526528
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
527529
}
528530

529-
$this->updateStatus(false);
530-
531531
return$this->processInformation['signaled'];
532532
}
533533

@@ -545,12 +545,12 @@ public function getTermSignal()
545545
{
546546
$this->requireProcessIsTerminated(__FUNCTION__);
547547

548-
if ($this->isSigchildEnabled()) {
548+
if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 ===$this->processInformation['termsig'])) {
549+
$this->stop(0);
550+
549551
thrownewRuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
550552
}
551553

552-
$this->updateStatus(false);
553-
554554
return$this->processInformation['termsig'];
555555
}
556556

@@ -567,8 +567,6 @@ public function hasBeenStopped()
567567
{
568568
$this->requireProcessIsTerminated(__FUNCTION__);
569569

570-
$this->updateStatus(false);
571-
572570
return$this->processInformation['stopped'];
573571
}
574572

@@ -585,8 +583,6 @@ public function getStopSignal()
585583
{
586584
$this->requireProcessIsTerminated(__FUNCTION__);
587585

588-
$this->updateStatus(false);
589-
590586
return$this->processInformation['stopsig'];
591587
}
592588

@@ -660,7 +656,7 @@ public function stop($timeout = 10, $signal = null)
660656
usleep(1000);
661657
}while ($this->isRunning() &&microtime(true) <$timeoutMicro);
662658

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

999995
if (!$this->useFileHandles &&$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
1000996
// 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')));
997+
$descriptors[3] =array('pipe','w');
998+
999+
$trap ='';
1000+
foreach (self::$posixSignalsas$s) {
1001+
$trap .="trap 'echo s$s >&3'$s;";
1002+
}
10021003

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

10061008
return$descriptors;
@@ -1047,10 +1049,13 @@ protected function updateStatus($blocking)
10471049
}
10481050

10491051
$this->processInformation =proc_get_status($this->process);
1050-
$this->captureExitCode();
10511052

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

1055+
if ($this->fallbackStatus &&$this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
1056+
$this->processInformation =$this->fallbackStatus +$this->processInformation;
1057+
}
1058+
10541059
if (!$this->processInformation['running']) {
10551060
$this->close();
10561061
}
@@ -1067,7 +1072,7 @@ protected function isSigchildEnabled()
10671072
returnself::$sigchild;
10681073
}
10691074

1070-
if (!function_exists('phpinfo')) {
1075+
if (!function_exists('phpinfo') ||defined('HHVM_VERSION')) {
10711076
returnself::$sigchild =false;
10721077
}
10731078

@@ -1093,24 +1098,24 @@ private function readPipes($blocking, $close)
10931098

10941099
$callback =$this->callback;
10951100
foreach ($resultas$type =>$data) {
1096-
if (3 ==$type) {
1097-
$this->fallbackExitcode = (int)$data;
1101+
if (3 ===$type) {
1102+
foreach (explode("\n",substr($data,0, -1))as$data) {
1103+
if ('p' ===$data[0]) {
1104+
$this->fallbackStatus['pid'] = (int)substr($data,1);
1105+
}elseif ('s' ===$data[0]) {
1106+
$this->fallbackStatus['signaled'] =true;
1107+
$this->fallbackStatus['exitcode'] = -1;
1108+
$this->fallbackStatus['termsig'] = (int)substr($data,1);
1109+
}elseif ('x' ===$data[0] && !isset($this->fallbackStatus['signaled'])) {
1110+
$this->fallbackStatus['exitcode'] = (int)substr($data,1);
1111+
}
1112+
}
10981113
}else {
10991114
$callback($type ===self::STDOUT ?self::OUT :self::ERR,$data);
11001115
}
11011116
}
11021117
}
11031118

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-
11141119
/**
11151120
* Closes process resource, closes file handles, sets the exitcode.
11161121
*
@@ -1120,19 +1125,19 @@ private function close()
11201125
{
11211126
$this->processPipes->close();
11221127
if (is_resource($this->process)) {
1123-
$exitcode =proc_close($this->process);
1124-
}else {
1125-
$exitcode = -1;
1128+
proc_close($this->process);
11261129
}
1127-
1128-
$this->exitcode = -1 !==$exitcode ?$exitcode : (null !==$this->exitcode ?$this->exitcode : -1);
1130+
$this->exitcode =$this->processInformation['exitcode'];
11291131
$this->status =self::STATUS_TERMINATED;
11301132

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'];
1133+
if (-1 ===$this->exitcode) {
1134+
if ($this->processInformation['signaled'] &&0 <$this->processInformation['termsig']) {
1135+
// if process has been signaled, no exitcode but a valid termsig, apply Unix convention
1136+
$this->exitcode =128 +$this->processInformation['termsig'];
1137+
}elseif ($this->enhanceSigchildCompatibility &&$this->isSigchildEnabled()) {
1138+
$this->processInformation['signaled'] =true;
1139+
$this->processInformation['termsig'] = -1;
1140+
}
11361141
}
11371142

11381143
// Free memory from self-reference callback created by buildCallback
@@ -1151,7 +1156,7 @@ private function resetProcessData()
11511156
$this->starttime =null;
11521157
$this->callback =null;
11531158
$this->exitcode =null;
1154-
$this->fallbackExitcode =null;
1159+
$this->fallbackStatus =array();
11551160
$this->processInformation =null;
11561161
$this->stdout =null;
11571162
$this->stderr =null;
@@ -1171,7 +1176,7 @@ private function resetProcessData()
11711176
* @return bool True if the signal was sent successfully, false otherwise
11721177
*
11731178
* @throws LogicException In case the process is not running
1174-
* @throws RuntimeException In case --enable-sigchild is activated
1179+
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
11751180
* @throws RuntimeException In case of failure
11761181
*/
11771182
privatefunctiondoSignal($signal,$throwException)
@@ -1184,9 +1189,9 @@ private function doSignal($signal, $throwException)
11841189
returnfalse;
11851190
}
11861191

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

11921197
returnfalse;
@@ -1211,7 +1216,10 @@ private function doSignal($signal, $throwException)
12111216
returnfalse;
12121217
}
12131218

1214-
$this->latestSignal =$signal;
1219+
$this->latestSignal = (int)$signal;
1220+
$this->fallbackStatus['signaled'] =true;
1221+
$this->fallbackStatus['exitcode'] = -1;
1222+
$this->fallbackStatus['termsig'] =$this->latestSignal;
12151223

12161224
returntrue;
12171225
}

‎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