8000 Add a Sigchild compatibility mode (set to false by default) · sam57/symfony@7bafc69 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7bafc69

Browse files
committed
Add a Sigchild compatibility mode (set to false by default)
This mode is required to use a hack to determine if the process finished with success when PHP has been compiled with the --enable-sigchild option
1 parent 5a4a73e commit 7bafc69

6 files changed

+441
-32
lines changed

src/Symfony/Component/Process/Process.php

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Process;
1313

14+
use Symfony\Component\Process\Exception\RuntimeException;
15+
1416
/**
1517
* Process is a thin wrapper around proc_* functions to ease
1618
* start independent PHP processes.
@@ -44,13 +46,16 @@ class Process
4446
private $stdout;
4547
private $stderr;
4648
private $enhanceWindowsCompatibility;
49+
private $enhanceSigchildCompatibility;
4750
private $pipes;
4851
private $process;
4952
private $status = self::STATUS_READY;
5053

5154
private $fileHandles;
5255
private $readBytes;
5356

57+
private static $sigchild;
58+
5459
/**
5560
* Exit codes translation table.
5661
*
@@ -134,6 +139,7 @@ public function __construct($commandline, $cwd = null, array $env = null, $stdin
134139
$this->stdin = $stdin;
135140
$this->setTimeout($timeout);
136141
$this->enhanceWindowsCompatibility = true;
142+
$this->enhanceSigchildCompatibility = !defined('PHP_WINDOWS_VERSION_BUILD') && $this->isSigchildEnabled();
137143
$this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options);
138144
}
139145

@@ -216,9 +222,16 @@ public function start($callback = null)
216222
array('pipe', 'r'), // stdin
217223
array('pipe', 'w'), // stdout
218224
array('pipe', 'w'), // stderr
219-
array('pipe', 'w') // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
220225
);
221-
$this->commandline = '('.$this->commandline.') 3>/dev/null; code=$?; echo $code >&3; exit $code';
226+
227+
if ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
228+
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
229+
$descriptors = array_merge($descriptors, array(array('pipe', 'w')));
230+
231+
$this->commandline = '('.$this->commandline.') 3>/dev/null; code=$?; echo $code >&3; exit $code';
232+
} else {
233+
$this->commandline = 'exec ' . $this->commandline;
234+
}
222235
}
223236

224237
$commandline = $this->commandline;
@@ -418,10 +431,16 @@ public function getErrorOutput()
418431
*
419432
* @return integer The exit status code
420433
*
434+
* @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
435+
*
421436
* @api
422437
*/
423438
public function getExitCode()
424439
{
440+
if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {
441+
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method');
442+
}
443+
425444
$this->updateStatus();
426445

427446
return $this->exitcode;
@@ -435,28 +454,30 @@ public function getExitCode()
435454
*
436455
* @return string A string representation for the exit status code
437456
*
457+
* @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
458+
*
438459
* @see http://tldp.org/LDP/abs/html/exitcodes.html
439460
* @see http://en.wikipedia.org/wiki/Unix_signal
440461
*/
441462
public function getExitCodeText()
442463
{
443-
$this->updateStatus();
464+
$exitcode = $this->getExitCode();
444465

445-
return isset(self::$exitCodes[$this->exitcode]) ? self::$exitCodes[$this->exitcode] : 'Unknown error';
466+
return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
446467
}
447468

448469
/**
449470
* Checks if the process ended successfully.
450471
*
451472
* @return Boolean true if the process ended successfully, false otherwise
452473
*
474+
* @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
475+
*
453476
* @api
454477
*/
455478
public function isSuccessful()
456479
{
457-
$this->updateStatus();
458-
459-
return 0 == $this->exitcode;
480+
return 0 == $this->getExitCode();
460481
}
461482

462483
/**
@@ -466,10 +487,16 @@ public function isSuccessful()
466487
*
467488
* @return Boolean
468489
*
490+
* @throws RuntimeException In case --enable-sigchild is activated
491+
*
469492
* @api
470493
*/
471494
public function hasBeenSignaled()
472495
{
496+
if ($this->isSigchildEnabled()) {
497+
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved');
498+
}
499+
473500
$this->updateStatus();
474501

475502
return $this->processInformation['signaled'];
@@ -482,10 +509,16 @@ public function hasBeenSignaled()
482509
*
483510
* @return integer
484511
*
512+
* @throws RuntimeException In case --enable-sigchild is activated
513+
*
485514
* @api
486515
*/
487516
public function getTermSignal()
488517
{
518+
if ($this->isSigchildEnabled()) {
519+
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved');
520+
}
521+
489522
$this->updateStatus();
490523

491524
return $this->processInformation['termsig'];
@@ -678,6 +711,30 @@ public function setEnhanceWindowsCompatibility($enhance)
678711
$this->enhanceWindowsCompatibility = (Boolean) $enhance;
679712
}
680713

714+
/**
715+
* Return whether sigchild compatibility mode is activated or not
716+
*
717+
* @return Boolean
718+
*/
719+
public function getEnhanceSigchildCompatibility()
720+
{
721+
return $this->enhanceSigchildCompatibility;
722+
}
723+
724+
/**
725+
* Activate sigchild compatibility mode
726+
*
727+
* Sigchild compatibility mode is required to get the exit code and
728+
* determine the success of a process when PHP has been compiled with
729+
* the --enable-sigchild option
730+
*
731+
* @param Boolean $enhance
732+
*/
733+
public function setEnhanceSigchildCompatibility($enhance)
734+
{
735+
$this->enhanceSigchildCompatibility = (Boolean) $enhance;
736+
}
737+
681738
/**
682739
* Builds up the callback used by wait().
683740
*
@@ -743,6 +800,23 @@ protected function updateOutput()
743800
}
744801
}
745802

803+
/**
804+
* Return whether PHP has been compiled with the '--enable-sigchild' option or not
805+
*
806+
* @return Boolean
807+
*/
808+
protected function isSigchildEnabled()
809+
{
810+
if (null !== self::$sigchild) {
811+
return self::$sigchild;
812+
}
813+
814+
ob_start();
815+
phpinfo(INFO_GENERAL);
816+
817+
return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
818+
}
819+
746820
/**
747821
* Handles the windows file handles fallbacks
748822
*

0 commit comments

Comments
 (0)
0