updated-packages
This commit is contained in:
280
vendor/symfony/process/Process.php
vendored
280
vendor/symfony/process/Process.php
vendored
@@ -30,37 +30,37 @@ use Symfony\Component\Process\Pipes\WindowsPipes;
|
||||
*/
|
||||
class Process implements \IteratorAggregate
|
||||
{
|
||||
const ERR = 'err';
|
||||
const OUT = 'out';
|
||||
public const ERR = 'err';
|
||||
public const OUT = 'out';
|
||||
|
||||
const STATUS_READY = 'ready';
|
||||
const STATUS_STARTED = 'started';
|
||||
const STATUS_TERMINATED = 'terminated';
|
||||
public const STATUS_READY = 'ready';
|
||||
public const STATUS_STARTED = 'started';
|
||||
public const STATUS_TERMINATED = 'terminated';
|
||||
|
||||
const STDIN = 0;
|
||||
const STDOUT = 1;
|
||||
const STDERR = 2;
|
||||
public const STDIN = 0;
|
||||
public const STDOUT = 1;
|
||||
public const STDERR = 2;
|
||||
|
||||
// Timeout Precision in seconds.
|
||||
const TIMEOUT_PRECISION = 0.2;
|
||||
public const TIMEOUT_PRECISION = 0.2;
|
||||
|
||||
const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking
|
||||
const ITER_KEEP_OUTPUT = 2; // By default, outputs are cleared while iterating, use this flag to keep them in memory
|
||||
const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating
|
||||
const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating
|
||||
public const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking
|
||||
public const ITER_KEEP_OUTPUT = 2; // By default, outputs are cleared while iterating, use this flag to keep them in memory
|
||||
public const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating
|
||||
public const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating
|
||||
|
||||
private $callback;
|
||||
private $hasCallback = false;
|
||||
private $commandline;
|
||||
private $cwd;
|
||||
private $env;
|
||||
private $env = [];
|
||||
private $input;
|
||||
private $starttime;
|
||||
private $lastOutputTime;
|
||||
private $timeout;
|
||||
private $idleTimeout;
|
||||
private $exitcode;
|
||||
private $fallbackStatus = array();
|
||||
private $fallbackStatus = [];
|
||||
private $processInformation;
|
||||
private $outputDisabled = false;
|
||||
private $stdout;
|
||||
@@ -69,7 +69,7 @@ class Process implements \IteratorAggregate
|
||||
private $status = self::STATUS_READY;
|
||||
private $incrementalOutputOffset = 0;
|
||||
private $incrementalErrorOutputOffset = 0;
|
||||
private $tty;
|
||||
private $tty = false;
|
||||
private $pty;
|
||||
|
||||
private $useFileHandles = false;
|
||||
@@ -85,7 +85,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* User-defined errors must use exit codes in the 64-113 range.
|
||||
*/
|
||||
public static $exitCodes = array(
|
||||
public static $exitCodes = [
|
||||
0 => 'OK',
|
||||
1 => 'General error',
|
||||
2 => 'Misuse of shell builtins',
|
||||
@@ -126,16 +126,16 @@ class Process implements \IteratorAggregate
|
||||
157 => 'Pollable event',
|
||||
// 158 - not defined
|
||||
159 => 'Bad syscall',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array $command The command to run and its arguments listed as separate entries
|
||||
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process
|
||||
* @param array|null $env The environment variables or null to use the same environment as the current PHP process
|
||||
* @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
|
||||
* @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input
|
||||
* @param int|float|null $timeout The timeout in seconds or null to disable
|
||||
*
|
||||
* @throws RuntimeException When proc_open is not installed
|
||||
* @throws LogicException When proc_open is not installed
|
||||
*/
|
||||
public function __construct($command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
|
||||
{
|
||||
@@ -144,7 +144,7 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
|
||||
if (!\is_array($command)) {
|
||||
@trigger_error(sprintf('Passing a command as string when creating a "%s" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided by the shell.', __CLASS__), E_USER_DEPRECATED);
|
||||
@trigger_error(sprintf('Passing a command as string when creating a "%s" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided by the shell.', __CLASS__), \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->commandline = $command;
|
||||
@@ -152,8 +152,8 @@ class Process implements \IteratorAggregate
|
||||
|
||||
// on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started
|
||||
// on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected
|
||||
// @see : https://bugs.php.net/bug.php?id=51800
|
||||
// @see : https://bugs.php.net/bug.php?id=50524
|
||||
// @see : https://bugs.php.net/51800
|
||||
// @see : https://bugs.php.net/50524
|
||||
if (null === $this->cwd && (\defined('ZEND_THREAD_SAFE') || '\\' === \DIRECTORY_SEPARATOR)) {
|
||||
$this->cwd = getcwd();
|
||||
}
|
||||
@@ -177,25 +177,40 @@ class Process implements \IteratorAggregate
|
||||
* In order to inject dynamic values into command-lines, we strongly recommend using placeholders.
|
||||
* This will save escaping values, which is not portable nor secure anyway:
|
||||
*
|
||||
* $process = Process::fromShellCommandline('my_command "$MY_VAR"');
|
||||
* $process = Process::fromShellCommandline('my_command "${:MY_VAR}"');
|
||||
* $process->run(null, ['MY_VAR' => $theValue]);
|
||||
*
|
||||
* @param string $command The command line to pass to the shell of the OS
|
||||
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process
|
||||
* @param array|null $env The environment variables or null to use the same environment as the current PHP process
|
||||
* @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
|
||||
* @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input
|
||||
* @param int|float|null $timeout The timeout in seconds or null to disable
|
||||
*
|
||||
* @throws RuntimeException When proc_open is not installed
|
||||
* @return static
|
||||
*
|
||||
* @throws LogicException When proc_open is not installed
|
||||
*/
|
||||
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
|
||||
{
|
||||
$process = new static(array(), $cwd, $env, $input, $timeout);
|
||||
$process = new static([], $cwd, $env, $input, $timeout);
|
||||
$process->commandline = $command;
|
||||
|
||||
return $process;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->stop(0);
|
||||
@@ -218,17 +233,18 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param callable|null $callback A PHP callback to run whenever there is some
|
||||
* output available on STDOUT or STDERR
|
||||
* @param array $env An array of additional env vars to set when running the process
|
||||
*
|
||||
* @return int The exit status code
|
||||
*
|
||||
* @throws RuntimeException When process can't be launched
|
||||
* @throws RuntimeException When process stopped after receiving signal
|
||||
* @throws LogicException In case a callback is provided and output has been disabled
|
||||
* @throws RuntimeException When process can't be launched
|
||||
* @throws RuntimeException When process is already running
|
||||
* @throws ProcessTimedOutException When process timed out
|
||||
* @throws ProcessSignaledException When process stopped after receiving signal
|
||||
* @throws LogicException In case a callback is provided and output has been disabled
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function run(callable $callback = null, array $env = array()): int
|
||||
public function run(callable $callback = null, array $env = []): int
|
||||
{
|
||||
$this->start($callback, $env);
|
||||
|
||||
@@ -241,16 +257,13 @@ class Process implements \IteratorAggregate
|
||||
* This is identical to run() except that an exception is thrown if the process
|
||||
* exits with a non-zero exit code.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @param array $env An array of additional env vars to set when running the process
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*
|
||||
* @throws ProcessFailedException if the process didn't terminate successfully
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function mustRun(callable $callback = null, array $env = array())
|
||||
public function mustRun(callable $callback = null, array $env = []): self
|
||||
{
|
||||
if (0 !== $this->run($callback, $env)) {
|
||||
throw new ProcessFailedException($this);
|
||||
@@ -273,16 +286,15 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param callable|null $callback A PHP callback to run whenever there is some
|
||||
* output available on STDOUT or STDERR
|
||||
* @param array $env An array of additional env vars to set when running the process
|
||||
*
|
||||
* @throws RuntimeException When process can't be launched
|
||||
* @throws RuntimeException When process is already running
|
||||
* @throws LogicException In case a callback is provided and output has been disabled
|
||||
*/
|
||||
public function start(callable $callback = null, array $env = array())
|
||||
public function start(callable $callback = null, array $env = [])
|
||||
{
|
||||
if ($this->isRunning()) {
|
||||
throw new RuntimeException('Process is already running');
|
||||
throw new RuntimeException('Process is already running.');
|
||||
}
|
||||
|
||||
$this->resetProcessData();
|
||||
@@ -291,28 +303,31 @@ class Process implements \IteratorAggregate
|
||||
$this->hasCallback = null !== $callback;
|
||||
$descriptors = $this->getDescriptors();
|
||||
|
||||
if ($this->env) {
|
||||
$env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env;
|
||||
}
|
||||
|
||||
$env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv();
|
||||
|
||||
if (\is_array($commandline = $this->commandline)) {
|
||||
$commandline = implode(' ', array_map(array($this, 'escapeArgument'), $commandline));
|
||||
$commandline = implode(' ', array_map([$this, 'escapeArgument'], $commandline));
|
||||
|
||||
if ('\\' !== \DIRECTORY_SEPARATOR) {
|
||||
// exec is mandatory to deal with sending a signal to the process
|
||||
$commandline = 'exec '.$commandline;
|
||||
}
|
||||
} else {
|
||||
$commandline = $this->replacePlaceholders($commandline, $env);
|
||||
}
|
||||
|
||||
if ($this->env) {
|
||||
$env += $this->env;
|
||||
}
|
||||
$env += $this->getDefaultEnv();
|
||||
|
||||
$options = array('suppress_errors' => true);
|
||||
$options = ['suppress_errors' => true];
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$options['bypass_shell'] = true;
|
||||
$commandline = $this->prepareWindowsCommandLine($commandline, $env);
|
||||
} 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');
|
||||
$descriptors[3] = ['pipe', 'w'];
|
||||
|
||||
// See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
|
||||
$commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
|
||||
@@ -323,18 +338,18 @@ class Process implements \IteratorAggregate
|
||||
$ptsWorkaround = fopen(__FILE__, 'r');
|
||||
}
|
||||
|
||||
$envPairs = array();
|
||||
$envPairs = [];
|
||||
foreach ($env as $k => $v) {
|
||||
if (false !== $v) {
|
||||
if (false !== $v && false === \in_array($k, ['argc', 'argv', 'ARGC', 'ARGV'], true)) {
|
||||
$envPairs[] = $k.'='.$v;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_dir($this->cwd)) {
|
||||
throw new RuntimeException('The provided cwd does not exist.');
|
||||
throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd));
|
||||
}
|
||||
|
||||
$this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $options);
|
||||
$this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $options);
|
||||
|
||||
if (!\is_resource($this->process)) {
|
||||
throw new RuntimeException('Unable to launch a new process.');
|
||||
@@ -360,9 +375,8 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param callable|null $callback A PHP callback to run whenever there is some
|
||||
* output available on STDOUT or STDERR
|
||||
* @param array $env An array of additional env vars to set when running the process
|
||||
*
|
||||
* @return $this
|
||||
* @return static
|
||||
*
|
||||
* @throws RuntimeException When process can't be launched
|
||||
* @throws RuntimeException When process is already running
|
||||
@@ -371,10 +385,10 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function restart(callable $callback = null, array $env = array())
|
||||
public function restart(callable $callback = null, array $env = []): self
|
||||
{
|
||||
if ($this->isRunning()) {
|
||||
throw new RuntimeException('Process is already running');
|
||||
throw new RuntimeException('Process is already running.');
|
||||
}
|
||||
|
||||
$process = clone $this;
|
||||
@@ -394,9 +408,9 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @return int The exitcode of the process
|
||||
*
|
||||
* @throws RuntimeException When process timed out
|
||||
* @throws RuntimeException When process stopped after receiving signal
|
||||
* @throws LogicException When process is not yet started
|
||||
* @throws ProcessTimedOutException When process timed out
|
||||
* @throws ProcessSignaledException When process stopped after receiving signal
|
||||
* @throws LogicException When process is not yet started
|
||||
*/
|
||||
public function wait(callable $callback = null)
|
||||
{
|
||||
@@ -407,7 +421,7 @@ class Process implements \IteratorAggregate
|
||||
if (null !== $callback) {
|
||||
if (!$this->processPipes->haveReadSupport()) {
|
||||
$this->stop(0);
|
||||
throw new \LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::wait"');
|
||||
throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::wait".');
|
||||
}
|
||||
$this->callback = $this->buildCallback($callback);
|
||||
}
|
||||
@@ -419,6 +433,7 @@ class Process implements \IteratorAggregate
|
||||
} while ($running);
|
||||
|
||||
while ($this->isRunning()) {
|
||||
$this->checkTimeout();
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
@@ -436,8 +451,9 @@ class Process implements \IteratorAggregate
|
||||
* from the output in real-time while writing the standard input to the process.
|
||||
* It allows to have feedback from the independent process during execution.
|
||||
*
|
||||
* @throws RuntimeException When process timed out
|
||||
* @throws LogicException When process is not yet started
|
||||
* @throws RuntimeException When process timed out
|
||||
* @throws LogicException When process is not yet started
|
||||
* @throws ProcessTimedOutException In case the timeout was reached
|
||||
*/
|
||||
public function waitUntil(callable $callback): bool
|
||||
{
|
||||
@@ -446,7 +462,7 @@ class Process implements \IteratorAggregate
|
||||
|
||||
if (!$this->processPipes->haveReadSupport()) {
|
||||
$this->stop(0);
|
||||
throw new \LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::waitUntil".');
|
||||
throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::waitUntil".');
|
||||
}
|
||||
$callback = $this->buildCallback($callback);
|
||||
|
||||
@@ -487,7 +503,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Sends a POSIX signal to the process.
|
||||
*
|
||||
* @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
|
||||
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
@@ -606,6 +622,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator($flags = 0)
|
||||
{
|
||||
$this->readPipesForOutput(__FUNCTION__, false);
|
||||
@@ -752,10 +769,10 @@ class Process implements \IteratorAggregate
|
||||
public function getExitCodeText()
|
||||
{
|
||||
if (null === $exitcode = $this->getExitCode()) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
|
||||
return self::$exitCodes[$exitcode] ?? 'Unknown error';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -895,7 +912,7 @@ class Process implements \IteratorAggregate
|
||||
* @param int|float $timeout The timeout in seconds
|
||||
* @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
|
||||
*
|
||||
* @return int The exit-code of the process
|
||||
* @return int|null The exit-code of the process or null if it's not running
|
||||
*/
|
||||
public function stop($timeout = 10, $signal = null)
|
||||
{
|
||||
@@ -935,7 +952,7 @@ class Process implements \IteratorAggregate
|
||||
{
|
||||
$this->lastOutputTime = microtime(true);
|
||||
|
||||
fseek($this->stdout, 0, SEEK_END);
|
||||
fseek($this->stdout, 0, \SEEK_END);
|
||||
fwrite($this->stdout, $line);
|
||||
fseek($this->stdout, $this->incrementalOutputOffset);
|
||||
}
|
||||
@@ -949,11 +966,19 @@ class Process implements \IteratorAggregate
|
||||
{
|
||||
$this->lastOutputTime = microtime(true);
|
||||
|
||||
fseek($this->stderr, 0, SEEK_END);
|
||||
fseek($this->stderr, 0, \SEEK_END);
|
||||
fwrite($this->stderr, $line);
|
||||
fseek($this->stderr, $this->incrementalErrorOutputOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last output time in seconds.
|
||||
*/
|
||||
public function getLastOutputTime(): ?float
|
||||
{
|
||||
return $this->lastOutputTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the command line to be executed.
|
||||
*
|
||||
@@ -961,7 +986,7 @@ class Process implements \IteratorAggregate
|
||||
*/
|
||||
public function getCommandLine()
|
||||
{
|
||||
return \is_array($this->commandline) ? implode(' ', array_map(array($this, 'escapeArgument'), $this->commandline)) : $this->commandline;
|
||||
return \is_array($this->commandline) ? implode(' ', array_map([$this, 'escapeArgument'], $this->commandline)) : $this->commandline;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -969,13 +994,13 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param string|array $commandline The command to execute
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since Symfony 4.2.
|
||||
*/
|
||||
public function setCommandLine($commandline)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), \E_USER_DEPRECATED);
|
||||
|
||||
$this->commandline = $commandline;
|
||||
|
||||
@@ -1003,13 +1028,13 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the process timeout (max. runtime).
|
||||
* Sets the process timeout (max. runtime) in seconds.
|
||||
*
|
||||
* To disable the timeout, set this value to null.
|
||||
*
|
||||
* @param int|float|null $timeout The timeout in seconds
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException if the timeout is negative
|
||||
*/
|
||||
@@ -1027,7 +1052,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param int|float|null $timeout The timeout in seconds
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws LogicException if the output is disabled
|
||||
* @throws InvalidArgumentException if the timeout is negative
|
||||
@@ -1048,7 +1073,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param bool $tty True to enabled and false to disable
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws RuntimeException In case the TTY mode is not supported
|
||||
*/
|
||||
@@ -1082,7 +1107,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param bool $bool
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
public function setPty($bool)
|
||||
{
|
||||
@@ -1122,7 +1147,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param string $cwd The new working directory
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setWorkingDirectory($cwd)
|
||||
{
|
||||
@@ -1144,25 +1169,12 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Sets the environment variables.
|
||||
*
|
||||
* Each environment variable value should be a string.
|
||||
* If it is an array, the variable is ignored.
|
||||
* If it is false or null, it will be removed when
|
||||
* env vars are otherwise inherited.
|
||||
* @param array<string|\Stringable> $env The new environment variables
|
||||
*
|
||||
* That happens in PHP when 'argv' is registered into
|
||||
* the $_ENV array for instance.
|
||||
*
|
||||
* @param array $env The new environment variables
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnv(array $env)
|
||||
{
|
||||
// Process can not handle env values that are arrays
|
||||
$env = array_filter($env, function ($value) {
|
||||
return !\is_array($value);
|
||||
});
|
||||
|
||||
$this->env = $env;
|
||||
|
||||
return $this;
|
||||
@@ -1185,7 +1197,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param string|int|float|bool|resource|\Traversable|null $input The content
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*
|
||||
* @throws LogicException In case the process is running
|
||||
*/
|
||||
@@ -1205,10 +1217,14 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param bool $inheritEnv
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since Symfony 4.4, env variables are always inherited
|
||||
*/
|
||||
public function inheritEnvironmentVariables($inheritEnv = true)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, env variables are always inherited.', __METHOD__), \E_USER_DEPRECATED);
|
||||
|
||||
if (!$inheritEnv) {
|
||||
throw new InvalidArgumentException('Not inheriting environment variables is not supported.');
|
||||
}
|
||||
@@ -1251,7 +1267,7 @@ class Process implements \IteratorAggregate
|
||||
static $isTtySupported;
|
||||
|
||||
if (null === $isTtySupported) {
|
||||
$isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
|
||||
$isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
|
||||
}
|
||||
|
||||
return $isTtySupported;
|
||||
@@ -1274,7 +1290,7 @@ class Process implements \IteratorAggregate
|
||||
return $result = false;
|
||||
}
|
||||
|
||||
return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes);
|
||||
return $result = (bool) @proc_open('echo 1 >/dev/null', [['pty'], ['pty'], ['pty']], $pipes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1307,25 +1323,21 @@ class Process implements \IteratorAggregate
|
||||
protected function buildCallback(callable $callback = null)
|
||||
{
|
||||
if ($this->outputDisabled) {
|
||||
return function ($type, $data) use ($callback) {
|
||||
if (null !== $callback) {
|
||||
return \call_user_func($callback, $type, $data);
|
||||
}
|
||||
return function ($type, $data) use ($callback): bool {
|
||||
return null !== $callback && $callback($type, $data);
|
||||
};
|
||||
}
|
||||
|
||||
$out = self::OUT;
|
||||
|
||||
return function ($type, $data) use ($callback, $out) {
|
||||
return function ($type, $data) use ($callback, $out): bool {
|
||||
if ($out == $type) {
|
||||
$this->addOutput($data);
|
||||
} else {
|
||||
$this->addErrorOutput($data);
|
||||
}
|
||||
|
||||
if (null !== $callback) {
|
||||
return \call_user_func($callback, $type, $data);
|
||||
}
|
||||
return null !== $callback && $callback($type, $data);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1370,9 +1382,9 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
|
||||
ob_start();
|
||||
phpinfo(INFO_GENERAL);
|
||||
phpinfo(\INFO_GENERAL);
|
||||
|
||||
return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
|
||||
return self::$sigchild = str_contains(ob_get_clean(), '--enable-sigchild');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1472,10 +1484,10 @@ class Process implements \IteratorAggregate
|
||||
$this->starttime = null;
|
||||
$this->callback = null;
|
||||
$this->exitcode = null;
|
||||
$this->fallbackStatus = array();
|
||||
$this->fallbackStatus = [];
|
||||
$this->processInformation = null;
|
||||
$this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+b');
|
||||
$this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+b');
|
||||
$this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
|
||||
$this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
|
||||
$this->process = null;
|
||||
$this->latestSignal = null;
|
||||
$this->status = self::STATUS_READY;
|
||||
@@ -1486,11 +1498,9 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Sends a POSIX signal to the process.
|
||||
*
|
||||
* @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
|
||||
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
|
||||
* @param bool $throwException Whether to throw exception in case signal failed
|
||||
*
|
||||
* @return bool True if the signal was sent successfully, false otherwise
|
||||
*
|
||||
* @throws LogicException In case the process is not running
|
||||
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
|
||||
* @throws RuntimeException In case of failure
|
||||
@@ -1519,7 +1529,7 @@ class Process implements \IteratorAggregate
|
||||
$ok = @proc_terminate($this->process, $signal);
|
||||
} elseif (\function_exists('posix_kill')) {
|
||||
$ok = @posix_kill($pid, $signal);
|
||||
} elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), array(2 => array('pipe', 'w')), $pipes)) {
|
||||
} elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), [2 => ['pipe', 'w']], $pipes)) {
|
||||
$ok = false === fgets($pipes[2]);
|
||||
}
|
||||
if (!$ok) {
|
||||
@@ -1539,11 +1549,11 @@ class Process implements \IteratorAggregate
|
||||
return true;
|
||||
}
|
||||
|
||||
private function prepareWindowsCommandLine(string $cmd, array &$env)
|
||||
private function prepareWindowsCommandLine(string $cmd, array &$env): string
|
||||
{
|
||||
$uid = uniqid('', true);
|
||||
$varCount = 0;
|
||||
$varCache = array();
|
||||
$varCache = [];
|
||||
$cmd = preg_replace_callback(
|
||||
'/"(?:(
|
||||
[^"%!^]*+
|
||||
@@ -1559,14 +1569,14 @@ class Process implements \IteratorAggregate
|
||||
if (isset($varCache[$m[0]])) {
|
||||
return $varCache[$m[0]];
|
||||
}
|
||||
if (false !== strpos($value = $m[1], "\0")) {
|
||||
if (str_contains($value = $m[1], "\0")) {
|
||||
$value = str_replace("\0", '?', $value);
|
||||
}
|
||||
if (false === strpbrk($value, "\"%!\n")) {
|
||||
return '"'.$value.'"';
|
||||
}
|
||||
|
||||
$value = str_replace(array('!LF!', '"^!"', '"^%"', '"^^"', '""'), array("\n", '!', '%', '^', '"'), $value);
|
||||
$value = str_replace(['!LF!', '"^!"', '"^%"', '"^^"', '""'], ["\n", '!', '%', '^', '"'], $value);
|
||||
$value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"';
|
||||
$var = $uid.++$varCount;
|
||||
|
||||
@@ -1593,7 +1603,7 @@ class Process implements \IteratorAggregate
|
||||
private function requireProcessIsStarted(string $functionName)
|
||||
{
|
||||
if (!$this->isStarted()) {
|
||||
throw new LogicException(sprintf('Process must be started before calling %s.', $functionName));
|
||||
throw new LogicException(sprintf('Process must be started before calling "%s()".', $functionName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1605,7 +1615,7 @@ class Process implements \IteratorAggregate
|
||||
private function requireProcessIsTerminated(string $functionName)
|
||||
{
|
||||
if (!$this->isTerminated()) {
|
||||
throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
|
||||
throw new LogicException(sprintf('Process must be terminated before calling "%s()".', $functionName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1620,7 +1630,7 @@ class Process implements \IteratorAggregate
|
||||
if ('\\' !== \DIRECTORY_SEPARATOR) {
|
||||
return "'".str_replace("'", "'\\''", $argument)."'";
|
||||
}
|
||||
if (false !== strpos($argument, "\0")) {
|
||||
if (str_contains($argument, "\0")) {
|
||||
$argument = str_replace("\0", '?', $argument);
|
||||
}
|
||||
if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) {
|
||||
@@ -1628,25 +1638,25 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
$argument = preg_replace('/(\\\\+)$/', '$1$1', $argument);
|
||||
|
||||
return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"';
|
||||
return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"';
|
||||
}
|
||||
|
||||
private function getDefaultEnv()
|
||||
private function replacePlaceholders(string $commandline, array $env)
|
||||
{
|
||||
$env = array();
|
||||
|
||||
foreach ($_SERVER as $k => $v) {
|
||||
if (\is_string($v) && false !== $v = getenv($k)) {
|
||||
$env[$k] = $v;
|
||||
return preg_replace_callback('/"\$\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\}"/', function ($matches) use ($commandline, $env) {
|
||||
if (!isset($env[$matches[1]]) || false === $env[$matches[1]]) {
|
||||
throw new InvalidArgumentException(sprintf('Command line is missing a value for parameter "%s": ', $matches[1]).$commandline);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($_ENV as $k => $v) {
|
||||
if (\is_string($v)) {
|
||||
$env[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $this->escapeArgument($env[$matches[1]]);
|
||||
}, $commandline);
|
||||
}
|
||||
|
||||
return $env;
|
||||
private function getDefaultEnv(): array
|
||||
{
|
||||
$env = getenv();
|
||||
$env = ('\\' === \DIRECTORY_SEPARATOR ? array_intersect_ukey($env, $_SERVER, 'strcasecmp') : array_intersect_key($env, $_SERVER)) ?: $env;
|
||||
|
||||
return $_ENV + ('\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($env, $_ENV, 'strcasecmp') : $env);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user