Dep: update

주로 PHAN
This commit is contained in:
2021-08-06 22:39:09 +09:00
parent 5310c2e7f6
commit b306601c72
1098 changed files with 92137 additions and 33228 deletions
+43 -1
View File
@@ -1,5 +1,39 @@
## [Unreleased]
## [2.0.2] - 2021-07-31
* Added: support for `xdebug_info('mode')` in Xdebug 3.1.
* Added: support for Psr\Log versions 2 and 3.
* Fixed: remove ini directives from non-cli HOST/PATH sections.
## [2.0.1] - 2021-05-05
* Fixed: don't restart if the cwd is a UNC path and cmd.exe will be invoked.
## [2.0.0] - 2021-04-09
* Break: this is a major release, see [UPGRADE.md](UPGRADE.md) for more information.
* Break: removed optional `$colorOption` constructor param and passthru fallback.
* Break: renamed `requiresRestart` param from `$isLoaded` to `$default`.
* Break: changed `restart` param `$command` from a string to an array.
* Added: support for Xdebug3 to only restart if Xdebug is not running with `xdebug.mode=off`.
* Added: `isXdebugActive()` method to determine if Xdebug is still running in the restart.
* Added: feature to bypass the shell in PHP-7.4+ by giving `proc_open` an array of arguments.
* Added: Process utility class to the API.
## [1.4.6] - 2021-03-25
* Fixed: fail restart if `proc_open` has been disabled in `disable_functions`.
* Fixed: enable Windows CTRL event handling in the restarted process.
## [1.4.5] - 2020-11-13
* Fixed: use `proc_open` when available for correct FD forwarding to the restarted process.
## [1.4.4] - 2020-10-24
* Fixed: exception if 'pcntl_signal' is disabled.
## [1.4.3] - 2020-08-19
* Fixed: restore SIGINT to default handler in restarted process if no other handler exists.
## [1.4.2] - 2020-06-04
* Fixed: ignore SIGINTs to let the restarted process handle them.
## [1.4.1] - 2020-03-01
* Fixed: restart fails if an ini file is empty.
@@ -57,7 +91,15 @@
* Break: the following class was renamed:
- `Composer\XdebugHandler` -> `Composer\XdebugHandler\XdebugHandler`
[Unreleased]: https://github.com/composer/xdebug-handler/compare/1.4.1...HEAD
[Unreleased]: https://github.com/composer/xdebug-handler/compare/2.0.2...HEAD
[2.0.2]: https://github.com/composer/xdebug-handler/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/composer/xdebug-handler/compare/2.0.0...2.0.1
[2.0.0]: https://github.com/composer/xdebug-handler/compare/1.4.6...2.0.0
[1.4.6]: https://github.com/composer/xdebug-handler/compare/1.4.5...1.4.6
[1.4.5]: https://github.com/composer/xdebug-handler/compare/1.4.4...1.4.5
[1.4.4]: https://github.com/composer/xdebug-handler/compare/1.4.3...1.4.4
[1.4.3]: https://github.com/composer/xdebug-handler/compare/1.4.2...1.4.3
[1.4.2]: https://github.com/composer/xdebug-handler/compare/1.4.1...1.4.2
[1.4.1]: https://github.com/composer/xdebug-handler/compare/1.4.0...1.4.1
[1.4.0]: https://github.com/composer/xdebug-handler/compare/1.3.3...1.4.0
[1.3.3]: https://github.com/composer/xdebug-handler/compare/1.3.2...1.3.3
+23 -20
View File
@@ -1,16 +1,19 @@
# composer/xdebug-handler
[![packagist](https://img.shields.io/packagist/v/composer/xdebug-handler.svg)](https://packagist.org/packages/composer/xdebug-handler)
[![linux build](https://img.shields.io/travis/composer/xdebug-handler/master.svg?label=linux+build)](https://travis-ci.org/composer/xdebug-handler)
[![windows build](https://img.shields.io/appveyor/ci/Seldaek/xdebug-handler/master.svg?label=windows+build)](https://ci.appveyor.com/project/Seldaek/xdebug-handler)
[![Continuous Integration](https://github.com/composer/xdebug-handler/workflows/Continuous%20Integration/badge.svg?branch=main)](https://github.com/composer/xdebug-handler/actions)
![license](https://img.shields.io/github/license/composer/xdebug-handler.svg)
![php](https://img.shields.io/packagist/php-v/composer/xdebug-handler.svg?colorB=8892BF&label=php)
Restart a CLI process without loading the Xdebug extension.
Restart a CLI process without loading the Xdebug extension, unless `xdebug.mode=off`.
Originally written as part of [composer/composer](https://github.com/composer/composer),
now extracted and made available as a stand-alone library.
### Version 2
Support added for Xdebug3. See [UPGRADE](UPGRADE.md) for more information.
## Installation
Install the latest version with:
@@ -32,21 +35,11 @@ $xdebug->check();
unset($xdebug);
```
The constructor takes two parameters:
#### _$envPrefix_
This is used to create distinct environment variables and is upper-cased and prepended to default base values. The above example enables the use of:
The constructor takes a single parameter, `$envPrefix`, which is upper-cased and prepended to default base values to create two distinct environment variables. The above example enables the use of:
- `MYAPP_ALLOW_XDEBUG=1` to override automatic restart and allow Xdebug
- `MYAPP_ORIGINAL_INIS` to obtain ini file locations in a restarted process
#### _$colorOption_
This optional value is added to the restart command-line and is needed to force color output in a piped child process. Only long-options are supported, for example `--ansi` or `--colors=always` etc.
If the original command-line contains an argument that pattern matches this value (for example `--no-ansi`, `--colors=never`) then _$colorOption_ is ignored.
If the pattern match ends with `=auto` (for example `--colors=auto`), the argument is replaced by _$colorOption_. Otherwise it is added at either the end of the command-line, or preceding the first double-dash `--` delimiter.
## Advanced Usage
* [How it works](#how-it-works)
@@ -63,12 +56,18 @@ A temporary ini file is created from the loaded (and scanned) ini files, with an
* `MYAPP_ALLOW_XDEBUG` is set with internal data to flag and use in the restart.
* The command-line and environment are [configured](#process-configuration) for the restart.
* The application is restarted in a new process using `passthru`.
* The application is restarted in a new process.
* The restart settings are stored in the environment.
* `MYAPP_ALLOW_XDEBUG` is unset.
* The application runs and exits.
* The main process exits with the exit code from the restarted process.
#### Signal handling
From PHP 7.1 with the pcntl extension loaded, asynchronous signal handling is automatically enabled. `SIGINT` is set to `SIG_IGN` in the parent
process and restored to `SIG_DFL` in the restarted process (if no other handler has been set).
From PHP 7.4 on Windows, `CTRL+C` and `CTRL+BREAK` handling is ignored in the parent process and automatically enabled in the restarted process.
### Limitations
There are a few things to be aware of when running inside a restarted process.
@@ -124,6 +123,9 @@ $version = XdebugHandler::getSkippedVersion();
# $version: '2.6.0' (for example), or an empty string
```
#### _isXdebugActive()_
Returns true if Xdebug is loaded and is running in an active mode (if it supports modes). Returns false if Xdebug is not loaded, or it is running with `xdebug.mode=off`.
### Setter methods
These methods implement a fluent interface and must be called before the main `check()` method.
@@ -232,15 +234,16 @@ The following environment settings can be used to troubleshoot unexpected behavi
### Extending the library
The API is defined by classes and their accessible elements that are not annotated as @internal. The main class has two protected methods that can be overridden to provide additional functionality:
#### _requiresRestart($isLoaded)_
By default the process will restart if Xdebug is loaded. Extending this method allows an application to decide, by returning a boolean (or equivalent) value. It is only called if `MYAPP_ALLOW_XDEBUG` is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden.
#### _requiresRestart($default)_
By default the process will restart if Xdebug is loaded and not running with `xdebug.mode=off`. Extending this method allows an application to decide, by returning a boolean (or equivalent) value.
It is only called if `MYAPP_ALLOW_XDEBUG` is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden.
Note that the [setMainScript()](#setmainscriptscript) and [setPersistent()](#setpersistent) setters can be used here, if required.
#### _restart($command)_
An application can extend this to modify the temporary ini file, its location given in the `tmpIni` property. New settings can be safely appended to the end of the data, which is `PHP_EOL` terminated.
Note that the `$command` parameter is the escaped command-line string that will be used for the new process and must be treated accordingly.
The `$command` parameter is an array of unescaped command-line arguments that will be used for the new process.
Remember to finish with `parent::restart($command)`.
@@ -259,7 +262,7 @@ class MyRestarter extends XdebugHandler
{
private $required;
protected function requiresRestart($isLoaded)
protected function requiresRestart($default)
{
if (Command::isHelp()) {
# No need to disable Xdebug for this
@@ -267,7 +270,7 @@ class MyRestarter extends XdebugHandler
}
$this->required = (bool) ini_get('phar.readonly');
return $isLoaded || $this->required;
return $this->required || $default;
}
protected function restart($command)
+30
View File
@@ -0,0 +1,30 @@
## Upgrading from 1.x
The default behaviour has changed from always restarting if Xdebug is loaded, to only restarting if
Xdebug is _active_. This has been introduced to support Xdebug3
[modes](https://xdebug.org/docs/all_settings#mode). Xdebug is considered active if it is loaded, and
for Xdebug3, if it is running in a mode other than `xdebug.mode=off`.
* Break: removed optional `$colorOption` constructor param and passthru fallback.
Just use `new XdebugHandler('myapp')` to instantiate the class and color support will be
detectable in the restarted process.
* Added: `isXdebugActive()` method to determine if Xdebug is still running in the restart.
Returns true if Xdebug is loaded and is running in an active mode (if it supports modes).
Returns false if Xdebug is not loaded, or it is running with `xdebug.mode=off`.
### Extending classes
* Break: renamed `requiresRestart` param from `$isLoaded` to `$default`.
This reflects the new default behaviour which is to restart only if Xdebug is active.
* Break: changed `restart` param `$command` from a string to an array.
Only important if you modified the string. `$command` is now an array of unescaped arguments.
* Added: Process utility class to the API.
This class was previously annotated as @internal and has been refactored due to recent changes.
+5 -3
View File
@@ -19,10 +19,11 @@
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0",
"psr/log": "^1.0"
"psr/log": "^1 || ^2 || ^3"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
"symfony/phpunit-bridge": "^4.2 || ^5",
"phpstan/phpstan": "^0.12.55"
},
"autoload": {
"psr-4": {
@@ -35,6 +36,7 @@
}
},
"scripts": {
"test": "phpunit"
"test": "vendor/bin/simple-phpunit",
"phpstan": "vendor/bin/phpstan analyse"
}
}
+15 -4
View File
@@ -49,8 +49,8 @@ class PhpConfig
public function usePersistent()
{
if ($data = $this->getDataAndReset()) {
Process::setEnv('PHPRC', $data['tmpIni']);
Process::setEnv('PHP_INI_SCAN_DIR', '');
$this->updateEnv('PHPRC', $data['tmpIni']);
$this->updateEnv('PHP_INI_SCAN_DIR', '');
}
return array();
@@ -64,10 +64,21 @@ class PhpConfig
private function getDataAndReset()
{
if ($data = XdebugHandler::getRestartSettings()) {
Process::setEnv('PHPRC', $data['phprc']);
Process::setEnv('PHP_INI_SCAN_DIR', $data['scanDir']);
$this->updateEnv('PHPRC', $data['phprc']);
$this->updateEnv('PHP_INI_SCAN_DIR', $data['scanDir']);
}
return $data;
}
/**
* Updates a restart settings value in the environment
*
* @param string $name
* @param string|false $value
*/
private function updateEnv($name, $value)
{
Process::setEnv($name, false !== $value ? $value : null);
}
}
+12 -79
View File
@@ -12,59 +12,12 @@
namespace Composer\XdebugHandler;
/**
* Provides utility functions to prepare a child process command-line and set
* environment variables in that process.
* Process utility functions
*
* @author John Stevenson <john-stevenson@blueyonder.co.uk>
* @internal
*/
class Process
{
/**
* Returns an array of parameters, including a color option if required
*
* A color option is needed because child process output is piped.
*
* @param array $args The script parameters
* @param string $colorOption The long option to force color output
*
* @return array
*/
public static function addColorOption(array $args, $colorOption)
{
if (!$colorOption
|| in_array($colorOption, $args)
|| !preg_match('/^--([a-z]+$)|(^--[a-z]+=)/', $colorOption, $matches)) {
return $args;
}
if (isset($matches[2])) {
// Handle --color(s)= options
if (false !== ($index = array_search($matches[2].'auto', $args))) {
$args[$index] = $colorOption;
return $args;
} elseif (preg_grep('/^'.$matches[2].'/', $args)) {
return $args;
}
} elseif (in_array('--no-'.$matches[1], $args)) {
return $args;
}
// Check for NO_COLOR variable (https://no-color.org/)
if (false !== getenv('NO_COLOR')) {
return $args;
}
if (false !== ($index = array_search('--', $args))) {
// Position option before double-dash delimiter
array_splice($args, $index, 0, $colorOption);
} else {
$args[] = $colorOption;
}
return $args;
}
/**
* Escapes a string to be used as a shell argument.
*
@@ -109,53 +62,33 @@ class Process
}
/**
* Returns true if the output stream supports colors
* Escapes an array of arguments that make up a shell command
*
* This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
* terminals via named pipes, so we can only check the environment.
* @param array $args Argument list, with the module name first
*
* @param mixed $output A valid CLI output stream
*
* @return bool
* @return string The escaped command line
*/
public static function supportsColor($output)
public static function escapeShellCommand(array $args)
{
if ('Hyper' === getenv('TERM_PROGRAM')) {
return true;
$cmd = self::escape(array_shift($args), true, true);
foreach ($args as $arg) {
$cmd .= ' '.self::escape($arg);
}
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
return (function_exists('sapi_windows_vt100_support')
&& sapi_windows_vt100_support($output))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
}
if (function_exists('stream_isatty')) {
return stream_isatty($output);
}
if (function_exists('posix_isatty')) {
return posix_isatty($output);
}
$stat = fstat($output);
// Check if formatted mode is S_IFCHR
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
return $cmd;
}
/**
* Makes putenv environment changes available in $_SERVER and $_ENV
*
* @param string $name
* @param string|false $value A false value unsets the variable
* @param string|null $value A null value unsets the variable
*
* @return bool Whether the environment variable was set
*/
public static function setEnv($name, $value = false)
public static function setEnv($name, $value = null)
{
$unset = false === $value;
$unset = null === $value;
if (!putenv($unset ? $name : $name.'='.$value)) {
return false;
+9 -3
View File
@@ -33,6 +33,7 @@ class Status
private $envAllowXdebug;
private $loaded;
private $logger;
private $modeOff;
private $time;
/**
@@ -91,7 +92,12 @@ class Status
private function reportCheck($loaded)
{
$this->loaded = $loaded;
list($version, $mode) = explode('|', $loaded);
if ($version) {
$this->loaded = '('.$version.')'.($mode ? ' mode='.$mode : '');
}
$this->modeOff = $mode === 'off';
$this->output('Checking '.$this->envAllowXdebug);
}
@@ -112,7 +118,7 @@ class Status
if ($this->loaded) {
$text = sprintf('No restart (%s)', $this->getEnvAllow());
if (!getenv($this->envAllowXdebug)) {
$text .= ' Allowed by application';
$text .= ' Allowed by '.($this->modeOff ? 'mode' : 'application');
}
$this->output($text);
}
@@ -157,7 +163,7 @@ class Status
*/
private function getLoadedMessage()
{
$loaded = $this->loaded ? sprintf('loaded (%s)', $this->loaded) : 'not loaded';
$loaded = $this->loaded ? sprintf('loaded %s', $this->loaded) : 'not loaded';
return 'The Xdebug extension is '.$loaded;
}
}
+126 -42
View File
@@ -30,13 +30,14 @@ class XdebugHandler
private static $inRestart;
private static $name;
private static $skipped;
private static $xdebugActive;
private $cli;
private $colorOption;
private $debug;
private $envAllowXdebug;
private $envOriginalInis;
private $loaded;
private $mode;
private $persistent;
private $script;
/** @var Status|null */
@@ -50,12 +51,11 @@ class XdebugHandler
* would result in MYAPP_ALLOW_XDEBUG and MYAPP_ORIGINAL_INIS.
*
* @param string $envPrefix Value used in environment variables
* @param string $colorOption Command-line long option to force color output
* @throws \RuntimeException If a parameter is invalid
* @throws \RuntimeException If the parameter is invalid
*/
public function __construct($envPrefix, $colorOption = '')
public function __construct($envPrefix)
{
if (!is_string($envPrefix) || empty($envPrefix) || !is_string($colorOption)) {
if (!is_string($envPrefix) || empty($envPrefix)) {
throw new \RuntimeException('Invalid constructor parameter');
}
@@ -63,13 +63,23 @@ class XdebugHandler
$this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW;
$this->envOriginalInis = self::$name.self::SUFFIX_INIS;
$this->colorOption = $colorOption;
if (extension_loaded('xdebug')) {
$ext = new \ReflectionExtension('xdebug');
$this->loaded = $ext->getVersion() ?: 'unknown';
$this->loaded = phpversion('xdebug') ?: 'unknown';
if (version_compare($this->loaded, '3.1', '>=')) {
/** @phpstan-ignore-next-line */
$modes = xdebug_info('mode');
$this->mode = empty($modes) ? 'off' : implode(',', $modes);
} elseif (false !== ($mode = ini_get('xdebug.mode'))) {
$this->mode = getenv('XDEBUG_MODE') ?: ($mode ?: 'off');
if (preg_match('/^,+$/', str_replace(' ', '', $this->mode))) {
$this->mode = 'off';
}
}
}
self::$xdebugActive = $this->loaded && $this->mode !== 'off';
if ($this->cli = PHP_SAPI === 'cli') {
$this->debug = getenv(self::DEBUG);
}
@@ -123,23 +133,22 @@ class XdebugHandler
*/
public function check()
{
$this->notify(Status::CHECK, $this->loaded);
$this->notify(Status::CHECK, $this->loaded.'|'.$this->mode);
$envArgs = explode('|', (string) getenv($this->envAllowXdebug));
if (empty($envArgs[0]) && $this->requiresRestart((bool) $this->loaded)) {
if (empty($envArgs[0]) && $this->requiresRestart(self::$xdebugActive)) {
// Restart required
$this->notify(Status::RESTART);
if ($this->prepareRestart()) {
$command = $this->getCommand();
$this->notify(Status::RESTARTING, $command);
$this->restart($command);
}
return;
}
if (self::RESTART_ID === $envArgs[0] && count($envArgs) === 5) {
// Restarting, so unset environment variable and use saved values
// Restarted, so unset environment variable and use saved values
$this->notify(Status::RESTARTED);
Process::setEnv($this->envAllowXdebug);
@@ -150,6 +159,8 @@ class XdebugHandler
self::$skipped = $envArgs[1];
}
$this->tryEnableSignals();
// Put restart settings in the environment
$this->setEnvRestartSettings($envArgs);
return;
@@ -204,7 +215,7 @@ class XdebugHandler
if (count($envArgs) !== 6
|| (!self::$inRestart && php_ini_loaded_file() !== $envArgs[0])) {
return;
return null;
}
return array(
@@ -228,21 +239,39 @@ class XdebugHandler
}
/**
* Returns true if Xdebug is loaded, or as directed by an extending class
* Returns whether Xdebug is loaded and active
*
* @param bool $isLoaded Whether Xdebug is loaded
* true: if Xdebug is loaded and is running in an active mode.
* false: if Xdebug is not loaded, or it is running with xdebug.mode=off.
*
* @return bool
*/
protected function requiresRestart($isLoaded)
public static function isXdebugActive()
{
return $isLoaded;
return self::$xdebugActive;
}
/**
* Allows an extending class to decide if there should be a restart
*
* The default is to restart if Xdebug is loaded and its mode is not "off".
* Do not typehint for 1.x compatibility.
*
* @param bool $default The default behaviour
*
* @return bool Whether the process should restart
*/
protected function requiresRestart($default)
{
return $default;
}
/**
* Allows an extending class to access the tmpIni
*
* @param string $command
* Do not typehint for 1.x compatibility
*
* @param array $command
*/
protected function restart($command)
{
@@ -252,12 +281,35 @@ class XdebugHandler
/**
* Executes the restarted command then deletes the tmp ini
*
* @param string $command
* @param array $command
*/
private function doRestart($command)
private function doRestart(array $command)
{
passthru($command, $exitCode);
$this->notify(Status::INFO, 'Restarted process exited '.$exitCode);
$this->tryEnableSignals();
$this->notify(Status::RESTARTING, implode(' ', $command));
if (PHP_VERSION_ID >= 70400) {
$cmd = $command;
} else {
$cmd = Process::escapeShellCommand($command);
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
// Outer quotes required on cmd string below PHP 8
$cmd = '"'.$cmd.'"';
}
}
$process = proc_open($cmd, array(), $pipes);
if (is_resource($process)) {
$exitCode = proc_close($process);
}
if (!isset($exitCode)) {
// Unlikely that php or the default shell cannot be invoked
$this->notify(Status::ERROR, 'Unable to restart process');
$exitCode = -1;
} else {
$this->notify(Status::INFO, 'Restarted process exited '.$exitCode);
}
if ($this->debug === '2') {
$this->notify(Status::INFO, 'Temp ini saved: '.$this->tmpIni);
@@ -329,7 +381,8 @@ class XdebugHandler
}
$content = '';
$regex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi';
$sectionRegex = '/^\s*\[(?:PATH|HOST)\s*=/mi';
$xdebugRegex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi';
foreach ($iniFiles as $file) {
// Check for inaccessible ini files
@@ -337,7 +390,11 @@ class XdebugHandler
$error = 'Unable to read ini: '.$file;
return false;
}
$content .= preg_replace($regex, ';$1', $data).PHP_EOL;
// Check and remove directives after HOST and PATH sections
if (preg_match($sectionRegex, $data, $matches, PREG_OFFSET_CAPTURE)) {
$data = substr($data, 0, $matches[0][1]);
}
$content .= preg_replace($xdebugRegex, ';$1', $data).PHP_EOL;
}
// Merge loaded settings into our ini content, if it is valid
@@ -353,9 +410,9 @@ class XdebugHandler
}
/**
* Returns the restart command line
* Returns the command line arguments for the restart
*
* @return string
* @return array
*/
private function getCommand()
{
@@ -367,18 +424,7 @@ class XdebugHandler
array_push($php, '-n', '-c', $this->tmpIni);
}
if (defined('STDOUT') && Process::supportsColor(STDOUT)) {
$args = Process::addColorOption($args, $this->colorOption);
}
$args = array_merge($php, array($this->script), $args);
$cmd = Process::escape(array_shift($args), true, true);
foreach ($args as $arg) {
$cmd .= ' '.Process::escape($arg);
}
return $cmd;
return array_merge($php, array($this->script), $args);
}
/**
@@ -490,7 +536,7 @@ class XdebugHandler
/**
* Adds restart settings to the environment
*
* @param string $envArgs
* @param string[] $envArgs
*/
private function setEnvRestartSettings($envArgs)
{
@@ -542,11 +588,12 @@ class XdebugHandler
* Returns true if there are no known configuration issues
*
* @param string $info Set by method
* @return bool
*/
private function checkConfiguration(&$info)
{
if (false !== strpos(ini_get('disable_functions'), 'passthru')) {
$info = 'passthru function is disabled';
if (!function_exists('proc_open')) {
$info = 'proc_open function is disabled';
return false;
}
@@ -560,6 +607,43 @@ class XdebugHandler
}
}
$workingDir = getcwd();
if (0 === strpos($workingDir, '\\\\')) {
if (defined('PHP_WINDOWS_VERSION_BUILD') && PHP_VERSION_ID < 70400) {
$info = 'cmd.exe does not support UNC paths: '.$workingDir;
return false;
}
}
return true;
}
/**
* Enables async signals and control interrupts in the restarted process
*
* Available on Unix PHP 7.1+ with the pcntl extension and Windows PHP 7.4+.
*/
private function tryEnableSignals()
{
if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
pcntl_async_signals(true);
$message = 'Async signals enabled';
if (!self::$inRestart) {
// Restarting, so ignore SIGINT in parent
pcntl_signal(SIGINT, SIG_IGN);
} elseif (is_int(pcntl_signal_get_handler(SIGINT))) {
// Restarted, no handler set so force default action
pcntl_signal(SIGINT, SIG_DFL);
}
}
if (!self::$inRestart && function_exists('sapi_windows_set_ctrl_handler')) {
// Restarting, so set a handler to ignore CTRL events in the parent.
// This ensures that CTRL+C events will be available in the child
// process without having to enable them there, which is unreliable.
sapi_windows_set_ctrl_handler(function ($evt) {});
}
}
}