mirror of
https://github.com/linuxserver/Heimdall.git
synced 2025-12-04 05:59:55 +09:00
Update to laravel 7
This commit is contained in:
3
vendor/symfony/process/.gitignore
vendored
3
vendor/symfony/process/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
26
vendor/symfony/process/CHANGELOG.md
vendored
26
vendor/symfony/process/CHANGELOG.md
vendored
@@ -1,6 +1,32 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
5.2.0
|
||||
-----
|
||||
|
||||
* added `Process::setOptions()` to set `Process` specific options
|
||||
* added option `create_new_console` to allow a subprocess to continue
|
||||
to run after the main script exited, both on Linux and on Windows
|
||||
|
||||
5.1.0
|
||||
-----
|
||||
|
||||
* added `Process::getStartTime()` to retrieve the start time of the process as float
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
||||
* removed `Process::inheritEnvironmentVariables()`
|
||||
* removed `PhpProcess::setPhpBinary()`
|
||||
* `Process` must be instantiated with a command array, use `Process::fromShellCommandline()` when the command should be parsed by the shell
|
||||
* removed `Process::setCommandLine()`
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
* deprecated `Process::inheritEnvironmentVariables()`: env variables are always inherited.
|
||||
* added `Process::getLastOutputTime()` method
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ use Symfony\Component\Process\Process;
|
||||
*/
|
||||
class ProcessTimedOutException extends RuntimeException
|
||||
{
|
||||
const TYPE_GENERAL = 1;
|
||||
const TYPE_IDLE = 2;
|
||||
public const TYPE_GENERAL = 1;
|
||||
public const TYPE_IDLE = 2;
|
||||
|
||||
private $process;
|
||||
private $timeoutType;
|
||||
|
||||
14
vendor/symfony/process/ExecutableFinder.php
vendored
14
vendor/symfony/process/ExecutableFinder.php
vendored
@@ -31,10 +31,8 @@ class ExecutableFinder
|
||||
|
||||
/**
|
||||
* Adds new possible suffix to check for executable.
|
||||
*
|
||||
* @param string $suffix
|
||||
*/
|
||||
public function addSuffix($suffix)
|
||||
public function addSuffix(string $suffix)
|
||||
{
|
||||
$this->suffixes[] = $suffix;
|
||||
}
|
||||
@@ -46,12 +44,12 @@ class ExecutableFinder
|
||||
* @param string|null $default The default to return if no executable is found
|
||||
* @param array $extraDirs Additional dirs to check into
|
||||
*
|
||||
* @return string|null The executable path or default value
|
||||
* @return string|null
|
||||
*/
|
||||
public function find($name, $default = null, array $extraDirs = [])
|
||||
public function find(string $name, string $default = null, array $extraDirs = [])
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$searchPath = array_merge(explode(PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
|
||||
$searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
|
||||
$dirs = [];
|
||||
foreach ($searchPath as $path) {
|
||||
// Silencing against https://bugs.php.net/69240
|
||||
@@ -65,7 +63,7 @@ class ExecutableFinder
|
||||
}
|
||||
} else {
|
||||
$dirs = array_merge(
|
||||
explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
|
||||
explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
|
||||
$extraDirs
|
||||
);
|
||||
}
|
||||
@@ -73,7 +71,7 @@ class ExecutableFinder
|
||||
$suffixes = [''];
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$pathExt = getenv('PATHEXT');
|
||||
$suffixes = array_merge($pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
|
||||
$suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
|
||||
}
|
||||
foreach ($suffixes as $suffix) {
|
||||
foreach ($dirs as $dir) {
|
||||
|
||||
8
vendor/symfony/process/InputStream.php
vendored
8
vendor/symfony/process/InputStream.php
vendored
@@ -17,6 +17,8 @@ use Symfony\Component\Process\Exception\RuntimeException;
|
||||
* Provides a way to continuously write to the input of a Process until the InputStream is closed.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @implements \IteratorAggregate<int, string>
|
||||
*/
|
||||
class InputStream implements \IteratorAggregate
|
||||
{
|
||||
@@ -45,7 +47,7 @@ class InputStream implements \IteratorAggregate
|
||||
return;
|
||||
}
|
||||
if ($this->isClosed()) {
|
||||
throw new RuntimeException(sprintf('%s is closed', static::class));
|
||||
throw new RuntimeException(sprintf('"%s" is closed.', static::class));
|
||||
}
|
||||
$this->input[] = ProcessUtils::validateInput(__METHOD__, $input);
|
||||
}
|
||||
@@ -66,6 +68,10 @@ class InputStream implements \IteratorAggregate
|
||||
return !$this->open;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Traversable<int, string>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
$this->open = true;
|
||||
|
||||
2
vendor/symfony/process/LICENSE
vendored
2
vendor/symfony/process/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2004-2019 Fabien Potencier
|
||||
Copyright (c) 2004-2022 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
18
vendor/symfony/process/PhpExecutableFinder.php
vendored
18
vendor/symfony/process/PhpExecutableFinder.php
vendored
@@ -29,16 +29,14 @@ class PhpExecutableFinder
|
||||
/**
|
||||
* Finds The PHP executable.
|
||||
*
|
||||
* @param bool $includeArgs Whether or not include command arguments
|
||||
*
|
||||
* @return string|false The PHP executable path or false if it cannot be found
|
||||
* @return string|false
|
||||
*/
|
||||
public function find($includeArgs = true)
|
||||
public function find(bool $includeArgs = true)
|
||||
{
|
||||
if ($php = getenv('PHP_BINARY')) {
|
||||
if (!is_executable($php)) {
|
||||
$command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v';
|
||||
if ($php = strtok(exec($command.' '.escapeshellarg($php)), PHP_EOL)) {
|
||||
if ($php = strtok(exec($command.' '.escapeshellarg($php)), \PHP_EOL)) {
|
||||
if (!is_executable($php)) {
|
||||
return false;
|
||||
}
|
||||
@@ -54,8 +52,8 @@ class PhpExecutableFinder
|
||||
$args = $includeArgs && $args ? ' '.implode(' ', $args) : '';
|
||||
|
||||
// PHP_BINARY return the current sapi executable
|
||||
if (PHP_BINARY && \in_array(\PHP_SAPI, ['cli', 'cli-server', 'phpdbg'], true)) {
|
||||
return PHP_BINARY.$args;
|
||||
if (\PHP_BINARY && \in_array(\PHP_SAPI, ['cgi-fcgi', 'cli', 'cli-server', 'phpdbg'], true)) {
|
||||
return \PHP_BINARY.$args;
|
||||
}
|
||||
|
||||
if ($php = getenv('PHP_PATH')) {
|
||||
@@ -72,11 +70,11 @@ class PhpExecutableFinder
|
||||
}
|
||||
}
|
||||
|
||||
if (@is_executable($php = PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) {
|
||||
if (@is_executable($php = \PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) {
|
||||
return $php;
|
||||
}
|
||||
|
||||
$dirs = [PHP_BINDIR];
|
||||
$dirs = [\PHP_BINDIR];
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$dirs[] = 'C:\xampp\php\\';
|
||||
}
|
||||
@@ -87,7 +85,7 @@ class PhpExecutableFinder
|
||||
/**
|
||||
* Finds the PHP executable arguments.
|
||||
*
|
||||
* @return array The PHP executable arguments
|
||||
* @return array
|
||||
*/
|
||||
public function findArguments()
|
||||
{
|
||||
|
||||
11
vendor/symfony/process/PhpProcess.php
vendored
11
vendor/symfony/process/PhpProcess.php
vendored
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Process;
|
||||
|
||||
use Symfony\Component\Process\Exception\LogicException;
|
||||
use Symfony\Component\Process\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
@@ -50,15 +51,11 @@ class PhpProcess extends Process
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path to the PHP binary to use.
|
||||
*
|
||||
* @deprecated since Symfony 4.2, use the $php argument of the constructor instead.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPhpBinary($php)
|
||||
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
|
||||
{
|
||||
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the $php argument of the constructor instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$this->setCommandLine($php);
|
||||
throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
22
vendor/symfony/process/Pipes/AbstractPipes.php
vendored
22
vendor/symfony/process/Pipes/AbstractPipes.php
vendored
@@ -47,17 +47,17 @@ abstract class AbstractPipes implements PipesInterface
|
||||
public function close()
|
||||
{
|
||||
foreach ($this->pipes as $pipe) {
|
||||
fclose($pipe);
|
||||
if (\is_resource($pipe)) {
|
||||
fclose($pipe);
|
||||
}
|
||||
}
|
||||
$this->pipes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a system call has been interrupted.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasSystemCallBeenInterrupted()
|
||||
protected function hasSystemCallBeenInterrupted(): bool
|
||||
{
|
||||
$lastError = $this->lastError;
|
||||
$this->lastError = null;
|
||||
@@ -90,10 +90,10 @@ abstract class AbstractPipes implements PipesInterface
|
||||
*
|
||||
* @throws InvalidArgumentException When an input iterator yields a non supported value
|
||||
*/
|
||||
protected function write()
|
||||
protected function write(): ?array
|
||||
{
|
||||
if (!isset($this->pipes[0])) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
$input = $this->input;
|
||||
|
||||
@@ -105,7 +105,7 @@ abstract class AbstractPipes implements PipesInterface
|
||||
} elseif (!isset($this->inputBuffer[0])) {
|
||||
if (!\is_string($input)) {
|
||||
if (!is_scalar($input)) {
|
||||
throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported', \get_class($this->input), \gettype($input)));
|
||||
throw new InvalidArgumentException(sprintf('"%s" yielded a value of type "%s", but only scalars and stream resources are supported.', get_debug_type($this->input), get_debug_type($input)));
|
||||
}
|
||||
$input = (string) $input;
|
||||
}
|
||||
@@ -122,7 +122,7 @@ abstract class AbstractPipes implements PipesInterface
|
||||
|
||||
// let's have a look if something changed in streams
|
||||
if (false === @stream_select($r, $w, $e, 0, 0)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($w as $stdin) {
|
||||
@@ -135,7 +135,7 @@ abstract class AbstractPipes implements PipesInterface
|
||||
}
|
||||
|
||||
if ($input) {
|
||||
for (;;) {
|
||||
while (true) {
|
||||
$data = fread($input, self::CHUNK_SIZE);
|
||||
if (!isset($data[0])) {
|
||||
break;
|
||||
@@ -166,12 +166,14 @@ abstract class AbstractPipes implements PipesInterface
|
||||
} elseif (!$w) {
|
||||
return [$this->pipes[0]];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function handleError($type, $msg)
|
||||
public function handleError(int $type, string $msg)
|
||||
{
|
||||
$this->lastError = $msg;
|
||||
}
|
||||
|
||||
18
vendor/symfony/process/Pipes/PipesInterface.php
vendored
18
vendor/symfony/process/Pipes/PipesInterface.php
vendored
@@ -20,21 +20,19 @@ namespace Symfony\Component\Process\Pipes;
|
||||
*/
|
||||
interface PipesInterface
|
||||
{
|
||||
const CHUNK_SIZE = 16384;
|
||||
public const CHUNK_SIZE = 16384;
|
||||
|
||||
/**
|
||||
* Returns an array of descriptors for the use of proc_open.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDescriptors();
|
||||
public function getDescriptors(): array;
|
||||
|
||||
/**
|
||||
* Returns an array of filenames indexed by their related stream in case these pipes use temporary files.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFiles();
|
||||
public function getFiles(): array;
|
||||
|
||||
/**
|
||||
* Reads data in file handles and pipes.
|
||||
@@ -44,21 +42,17 @@ interface PipesInterface
|
||||
*
|
||||
* @return string[] An array of read data indexed by their fd
|
||||
*/
|
||||
public function readAndWrite($blocking, $close = false);
|
||||
public function readAndWrite(bool $blocking, bool $close = false): array;
|
||||
|
||||
/**
|
||||
* Returns if the current state has open file handles or pipes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function areOpen();
|
||||
public function areOpen(): bool;
|
||||
|
||||
/**
|
||||
* Returns if pipes are able to read output.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function haveReadSupport();
|
||||
public function haveReadSupport(): bool;
|
||||
|
||||
/**
|
||||
* Closes file handles and pipes.
|
||||
|
||||
22
vendor/symfony/process/Pipes/UnixPipes.php
vendored
22
vendor/symfony/process/Pipes/UnixPipes.php
vendored
@@ -35,6 +35,16 @@ class UnixPipes extends AbstractPipes
|
||||
parent::__construct($input);
|
||||
}
|
||||
|
||||
public function __sleep(): array
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
@@ -43,7 +53,7 @@ class UnixPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescriptors()
|
||||
public function getDescriptors(): array
|
||||
{
|
||||
if (!$this->haveReadSupport) {
|
||||
$nullstream = fopen('/dev/null', 'c');
|
||||
@@ -81,7 +91,7 @@ class UnixPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFiles()
|
||||
public function getFiles(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
@@ -89,7 +99,7 @@ class UnixPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function readAndWrite($blocking, $close = false)
|
||||
public function readAndWrite(bool $blocking, bool $close = false): array
|
||||
{
|
||||
$this->unblock();
|
||||
$w = $this->write();
|
||||
@@ -118,7 +128,7 @@ class UnixPipes extends AbstractPipes
|
||||
$read[$type = array_search($pipe, $this->pipes, true)] = '';
|
||||
|
||||
do {
|
||||
$data = fread($pipe, self::CHUNK_SIZE);
|
||||
$data = @fread($pipe, self::CHUNK_SIZE);
|
||||
$read[$type] .= $data;
|
||||
} while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));
|
||||
|
||||
@@ -138,7 +148,7 @@ class UnixPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function haveReadSupport()
|
||||
public function haveReadSupport(): bool
|
||||
{
|
||||
return $this->haveReadSupport;
|
||||
}
|
||||
@@ -146,7 +156,7 @@ class UnixPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function areOpen()
|
||||
public function areOpen(): bool
|
||||
{
|
||||
return (bool) $this->pipes;
|
||||
}
|
||||
|
||||
47
vendor/symfony/process/Pipes/WindowsPipes.php
vendored
47
vendor/symfony/process/Pipes/WindowsPipes.php
vendored
@@ -17,8 +17,8 @@ use Symfony\Component\Process\Process;
|
||||
/**
|
||||
* WindowsPipes implementation uses temporary files as handles.
|
||||
*
|
||||
* @see https://bugs.php.net/bug.php?id=51800
|
||||
* @see https://bugs.php.net/bug.php?id=65650
|
||||
* @see https://bugs.php.net/51800
|
||||
* @see https://bugs.php.net/65650
|
||||
*
|
||||
* @author Romain Neutron <imprec@gmail.com>
|
||||
*
|
||||
@@ -43,7 +43,7 @@ class WindowsPipes extends AbstractPipes
|
||||
// Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big.
|
||||
// Workaround for this problem is to use temporary files instead of pipes on Windows platform.
|
||||
//
|
||||
// @see https://bugs.php.net/bug.php?id=51800
|
||||
// @see https://bugs.php.net/51800
|
||||
$pipes = [
|
||||
Process::STDOUT => Process::OUT,
|
||||
Process::STDERR => Process::ERR,
|
||||
@@ -56,20 +56,23 @@ class WindowsPipes extends AbstractPipes
|
||||
$file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
|
||||
|
||||
if (!$h = fopen($file.'.lock', 'w')) {
|
||||
if (file_exists($file.'.lock')) {
|
||||
continue 2;
|
||||
}
|
||||
restore_error_handler();
|
||||
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $lastError));
|
||||
throw new RuntimeException('A temporary file could not be opened to write the process output: '.$lastError);
|
||||
}
|
||||
if (!flock($h, LOCK_EX | LOCK_NB)) {
|
||||
if (!flock($h, \LOCK_EX | \LOCK_NB)) {
|
||||
continue 2;
|
||||
}
|
||||
if (isset($this->lockHandles[$pipe])) {
|
||||
flock($this->lockHandles[$pipe], LOCK_UN);
|
||||
flock($this->lockHandles[$pipe], \LOCK_UN);
|
||||
fclose($this->lockHandles[$pipe]);
|
||||
}
|
||||
$this->lockHandles[$pipe] = $h;
|
||||
|
||||
if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) {
|
||||
flock($this->lockHandles[$pipe], LOCK_UN);
|
||||
if (!($h = fopen($file, 'w')) || !fclose($h) || !$h = fopen($file, 'r')) {
|
||||
flock($this->lockHandles[$pipe], \LOCK_UN);
|
||||
fclose($this->lockHandles[$pipe]);
|
||||
unset($this->lockHandles[$pipe]);
|
||||
continue 2;
|
||||
@@ -85,6 +88,16 @@ class WindowsPipes extends AbstractPipes
|
||||
parent::__construct($input);
|
||||
}
|
||||
|
||||
public function __sleep(): array
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
@@ -93,7 +106,7 @@ class WindowsPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescriptors()
|
||||
public function getDescriptors(): array
|
||||
{
|
||||
if (!$this->haveReadSupport) {
|
||||
$nullstream = fopen('NUL', 'c');
|
||||
@@ -105,8 +118,8 @@ class WindowsPipes extends AbstractPipes
|
||||
];
|
||||
}
|
||||
|
||||
// We're not using pipe on Windows platform as it hangs (https://bugs.php.net/bug.php?id=51800)
|
||||
// We're not using file handles as it can produce corrupted output https://bugs.php.net/bug.php?id=65650
|
||||
// We're not using pipe on Windows platform as it hangs (https://bugs.php.net/51800)
|
||||
// We're not using file handles as it can produce corrupted output https://bugs.php.net/65650
|
||||
// So we redirect output within the commandline and pass the nul device to the process
|
||||
return [
|
||||
['pipe', 'r'],
|
||||
@@ -118,7 +131,7 @@ class WindowsPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFiles()
|
||||
public function getFiles(): array
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
@@ -126,7 +139,7 @@ class WindowsPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function readAndWrite($blocking, $close = false)
|
||||
public function readAndWrite(bool $blocking, bool $close = false): array
|
||||
{
|
||||
$this->unblock();
|
||||
$w = $this->write();
|
||||
@@ -149,7 +162,7 @@ class WindowsPipes extends AbstractPipes
|
||||
if ($close) {
|
||||
ftruncate($fileHandle, 0);
|
||||
fclose($fileHandle);
|
||||
flock($this->lockHandles[$type], LOCK_UN);
|
||||
flock($this->lockHandles[$type], \LOCK_UN);
|
||||
fclose($this->lockHandles[$type]);
|
||||
unset($this->fileHandles[$type], $this->lockHandles[$type]);
|
||||
}
|
||||
@@ -161,7 +174,7 @@ class WindowsPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function haveReadSupport()
|
||||
public function haveReadSupport(): bool
|
||||
{
|
||||
return $this->haveReadSupport;
|
||||
}
|
||||
@@ -169,7 +182,7 @@ class WindowsPipes extends AbstractPipes
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function areOpen()
|
||||
public function areOpen(): bool
|
||||
{
|
||||
return $this->pipes && $this->fileHandles;
|
||||
}
|
||||
@@ -183,7 +196,7 @@ class WindowsPipes extends AbstractPipes
|
||||
foreach ($this->fileHandles as $type => $handle) {
|
||||
ftruncate($handle, 0);
|
||||
fclose($handle);
|
||||
flock($this->lockHandles[$type], LOCK_UN);
|
||||
flock($this->lockHandles[$type], \LOCK_UN);
|
||||
fclose($this->lockHandles[$type]);
|
||||
}
|
||||
$this->fileHandles = $this->lockHandles = [];
|
||||
|
||||
401
vendor/symfony/process/Process.php
vendored
401
vendor/symfony/process/Process.php
vendored
@@ -27,27 +27,29 @@ use Symfony\Component\Process\Pipes\WindowsPipes;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Romain Neutron <imprec@gmail.com>
|
||||
*
|
||||
* @implements \IteratorAggregate<string, string>
|
||||
*/
|
||||
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;
|
||||
@@ -69,8 +71,9 @@ class Process implements \IteratorAggregate
|
||||
private $status = self::STATUS_READY;
|
||||
private $incrementalOutputOffset = 0;
|
||||
private $incrementalErrorOutputOffset = 0;
|
||||
private $tty;
|
||||
private $tty = false;
|
||||
private $pty;
|
||||
private $options = ['suppress_errors' => true, 'bypass_shell' => true];
|
||||
|
||||
private $useFileHandles = false;
|
||||
/** @var PipesInterface */
|
||||
@@ -132,28 +135,24 @@ class Process implements \IteratorAggregate
|
||||
* @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)
|
||||
public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60)
|
||||
{
|
||||
if (!\function_exists('proc_open')) {
|
||||
throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.');
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$this->commandline = $command;
|
||||
$this->cwd = $cwd;
|
||||
|
||||
// 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,16 +176,18 @@ 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)
|
||||
{
|
||||
@@ -196,9 +197,26 @@ class Process implements \IteratorAggregate
|
||||
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);
|
||||
if ($this->options['create_new_console'] ?? false) {
|
||||
$this->processPipes->close();
|
||||
} else {
|
||||
$this->stop(0);
|
||||
}
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
@@ -218,13 +236,14 @@ 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
|
||||
*/
|
||||
@@ -241,16 +260,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 = [])
|
||||
public function mustRun(callable $callback = null, array $env = []): self
|
||||
{
|
||||
if (0 !== $this->run($callback, $env)) {
|
||||
throw new ProcessFailedException($this);
|
||||
@@ -273,7 +289,6 @@ 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
|
||||
@@ -282,7 +297,7 @@ class Process implements \IteratorAggregate
|
||||
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,6 +306,12 @@ 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([$this, 'escapeArgument'], $commandline));
|
||||
|
||||
@@ -298,17 +319,11 @@ class Process implements \IteratorAggregate
|
||||
// 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 = ['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
|
||||
@@ -325,7 +340,7 @@ class Process implements \IteratorAggregate
|
||||
|
||||
$envPairs = [];
|
||||
foreach ($env as $k => $v) {
|
||||
if (false !== $v) {
|
||||
if (false !== $v && false === \in_array($k, ['argc', 'argv', 'ARGC', 'ARGV'], true)) {
|
||||
$envPairs[] = $k.'='.$v;
|
||||
}
|
||||
}
|
||||
@@ -334,7 +349,7 @@ class Process implements \IteratorAggregate
|
||||
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, $this->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 = [])
|
||||
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);
|
||||
}
|
||||
@@ -437,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
|
||||
{
|
||||
@@ -447,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);
|
||||
|
||||
@@ -488,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
|
||||
*
|
||||
@@ -496,7 +511,7 @@ class Process implements \IteratorAggregate
|
||||
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
|
||||
* @throws RuntimeException In case of failure
|
||||
*/
|
||||
public function signal($signal)
|
||||
public function signal(int $signal)
|
||||
{
|
||||
$this->doSignal($signal, true);
|
||||
|
||||
@@ -517,7 +532,7 @@ class Process implements \IteratorAggregate
|
||||
throw new RuntimeException('Disabling output while the process is running is not possible.');
|
||||
}
|
||||
if (null !== $this->idleTimeout) {
|
||||
throw new LogicException('Output can not be disabled while an idle timeout is set.');
|
||||
throw new LogicException('Output cannot be disabled while an idle timeout is set.');
|
||||
}
|
||||
|
||||
$this->outputDisabled = true;
|
||||
@@ -556,7 +571,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Returns the current output of the process (STDOUT).
|
||||
*
|
||||
* @return string The process output
|
||||
* @return string
|
||||
*
|
||||
* @throws LogicException in case the output has been disabled
|
||||
* @throws LogicException In case the process is not started
|
||||
@@ -578,7 +593,7 @@ class Process implements \IteratorAggregate
|
||||
* In comparison with the getOutput method which always return the whole
|
||||
* output, this one returns the new output since the last call.
|
||||
*
|
||||
* @return string The process output since the last call
|
||||
* @return string
|
||||
*
|
||||
* @throws LogicException in case the output has been disabled
|
||||
* @throws LogicException In case the process is not started
|
||||
@@ -605,9 +620,10 @@ class Process implements \IteratorAggregate
|
||||
* @throws LogicException in case the output has been disabled
|
||||
* @throws LogicException In case the process is not started
|
||||
*
|
||||
* @return \Generator
|
||||
* @return \Generator<string, string>
|
||||
*/
|
||||
public function getIterator($flags = 0)
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator(int $flags = 0)
|
||||
{
|
||||
$this->readPipesForOutput(__FUNCTION__, false);
|
||||
|
||||
@@ -671,7 +687,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Returns the current error output of the process (STDERR).
|
||||
*
|
||||
* @return string The process error output
|
||||
* @return string
|
||||
*
|
||||
* @throws LogicException in case the output has been disabled
|
||||
* @throws LogicException In case the process is not started
|
||||
@@ -694,7 +710,7 @@ class Process implements \IteratorAggregate
|
||||
* whole error output, this one returns the new error output since the last
|
||||
* call.
|
||||
*
|
||||
* @return string The process error output since the last call
|
||||
* @return string
|
||||
*
|
||||
* @throws LogicException in case the output has been disabled
|
||||
* @throws LogicException In case the process is not started
|
||||
@@ -753,16 +769,16 @@ 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';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the process ended successfully.
|
||||
*
|
||||
* @return bool true if the process ended successfully, false otherwise
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessful()
|
||||
{
|
||||
@@ -800,7 +816,7 @@ class Process implements \IteratorAggregate
|
||||
$this->requireProcessIsTerminated(__FUNCTION__);
|
||||
|
||||
if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) {
|
||||
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
|
||||
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal cannot be retrieved.');
|
||||
}
|
||||
|
||||
return $this->processInformation['termsig'];
|
||||
@@ -841,7 +857,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Checks if the process is currently running.
|
||||
*
|
||||
* @return bool true if the process is currently running, false otherwise
|
||||
* @return bool
|
||||
*/
|
||||
public function isRunning()
|
||||
{
|
||||
@@ -857,7 +873,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Checks if the process has been started with no regard to the current state.
|
||||
*
|
||||
* @return bool true if status is ready, false otherwise
|
||||
* @return bool
|
||||
*/
|
||||
public function isStarted()
|
||||
{
|
||||
@@ -867,7 +883,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Checks if the process is terminated.
|
||||
*
|
||||
* @return bool true if process is terminated, false otherwise
|
||||
* @return bool
|
||||
*/
|
||||
public function isTerminated()
|
||||
{
|
||||
@@ -881,7 +897,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* The status is one of: ready, started, terminated.
|
||||
*
|
||||
* @return string The current process status
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
@@ -896,9 +912,9 @@ 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)
|
||||
public function stop(float $timeout = 10, int $signal = null)
|
||||
{
|
||||
$timeoutMicro = microtime(true) + $timeout;
|
||||
if ($this->isRunning()) {
|
||||
@@ -936,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);
|
||||
}
|
||||
@@ -950,15 +966,23 @@ 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.
|
||||
*
|
||||
* @return string The command to execute
|
||||
* @return string
|
||||
*/
|
||||
public function getCommandLine()
|
||||
{
|
||||
@@ -966,27 +990,9 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command line to be executed.
|
||||
* Gets the process timeout in seconds (max. runtime).
|
||||
*
|
||||
* @param string|array $commandline The command to execute
|
||||
*
|
||||
* @return self The current Process instance
|
||||
*
|
||||
* @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);
|
||||
|
||||
$this->commandline = $commandline;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the process timeout (max. runtime).
|
||||
*
|
||||
* @return float|null The timeout in seconds or null if it's disabled
|
||||
* @return float|null
|
||||
*/
|
||||
public function getTimeout()
|
||||
{
|
||||
@@ -994,9 +1000,9 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the process idle timeout (max. time since last output).
|
||||
* Gets the process idle timeout in seconds (max. time since last output).
|
||||
*
|
||||
* @return float|null The timeout in seconds or null if it's disabled
|
||||
* @return float|null
|
||||
*/
|
||||
public function getIdleTimeout()
|
||||
{
|
||||
@@ -1004,17 +1010,15 @@ 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
|
||||
*/
|
||||
public function setTimeout($timeout)
|
||||
public function setTimeout(?float $timeout)
|
||||
{
|
||||
$this->timeout = $this->validateTimeout($timeout);
|
||||
|
||||
@@ -1022,21 +1026,19 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the process idle timeout (max. time since last output).
|
||||
* Sets the process idle timeout (max. time since last output) 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 LogicException if the output is disabled
|
||||
* @throws InvalidArgumentException if the timeout is negative
|
||||
*/
|
||||
public function setIdleTimeout($timeout)
|
||||
public function setIdleTimeout(?float $timeout)
|
||||
{
|
||||
if (null !== $timeout && $this->outputDisabled) {
|
||||
throw new LogicException('Idle timeout can not be set while the output is disabled.');
|
||||
throw new LogicException('Idle timeout cannot be set while the output is disabled.');
|
||||
}
|
||||
|
||||
$this->idleTimeout = $this->validateTimeout($timeout);
|
||||
@@ -1047,13 +1049,11 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Enables or disables the TTY mode.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function setTty($tty)
|
||||
public function setTty(bool $tty)
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR && $tty) {
|
||||
throw new RuntimeException('TTY mode is not supported on Windows platform.');
|
||||
@@ -1063,7 +1063,7 @@ class Process implements \IteratorAggregate
|
||||
throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
|
||||
}
|
||||
|
||||
$this->tty = (bool) $tty;
|
||||
$this->tty = $tty;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1071,7 +1071,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Checks if the TTY mode is enabled.
|
||||
*
|
||||
* @return bool true if the TTY mode is enabled, false otherwise
|
||||
* @return bool
|
||||
*/
|
||||
public function isTty()
|
||||
{
|
||||
@@ -1081,13 +1081,11 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Sets PTY mode.
|
||||
*
|
||||
* @param bool $bool
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
public function setPty($bool)
|
||||
public function setPty(bool $bool)
|
||||
{
|
||||
$this->pty = (bool) $bool;
|
||||
$this->pty = $bool;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -1105,7 +1103,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Gets the working directory.
|
||||
*
|
||||
* @return string|null The current working directory or null on failure
|
||||
* @return string|null
|
||||
*/
|
||||
public function getWorkingDirectory()
|
||||
{
|
||||
@@ -1121,11 +1119,9 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Sets the current working directory.
|
||||
*
|
||||
* @param string $cwd The new working directory
|
||||
*
|
||||
* @return self The current Process instance
|
||||
* @return $this
|
||||
*/
|
||||
public function setWorkingDirectory($cwd)
|
||||
public function setWorkingDirectory(string $cwd)
|
||||
{
|
||||
$this->cwd = $cwd;
|
||||
|
||||
@@ -1135,7 +1131,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Gets the environment variables.
|
||||
*
|
||||
* @return array The current environment variables
|
||||
* @return array
|
||||
*/
|
||||
public function getEnv()
|
||||
{
|
||||
@@ -1145,25 +1141,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;
|
||||
@@ -1172,7 +1155,7 @@ class Process implements \IteratorAggregate
|
||||
/**
|
||||
* Gets the Process input.
|
||||
*
|
||||
* @return resource|string|\Iterator|null The Process input
|
||||
* @return resource|string|\Iterator|null
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
@@ -1186,14 +1169,14 @@ 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
|
||||
*/
|
||||
public function setInput($input)
|
||||
{
|
||||
if ($this->isRunning()) {
|
||||
throw new LogicException('Input can not be set while the process is running.');
|
||||
throw new LogicException('Input cannot be set while the process is running.');
|
||||
}
|
||||
|
||||
$this->input = ProcessUtils::validateInput(__METHOD__, $input);
|
||||
@@ -1201,22 +1184,6 @@ class Process implements \IteratorAggregate
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether environment variables will be inherited or not.
|
||||
*
|
||||
* @param bool $inheritEnv
|
||||
*
|
||||
* @return self The current Process instance
|
||||
*/
|
||||
public function inheritEnvironmentVariables($inheritEnv = true)
|
||||
{
|
||||
if (!$inheritEnv) {
|
||||
throw new InvalidArgumentException('Not inheriting environment variables is not supported.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a check between the timeout definition and the time the process started.
|
||||
*
|
||||
@@ -1244,6 +1211,44 @@ class Process implements \IteratorAggregate
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws LogicException in case process is not started
|
||||
*/
|
||||
public function getStartTime(): float
|
||||
{
|
||||
if (!$this->isStarted()) {
|
||||
throw new LogicException('Start time is only available after process start.');
|
||||
}
|
||||
|
||||
return $this->starttime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines options to pass to the underlying proc_open().
|
||||
*
|
||||
* @see https://php.net/proc_open for the options supported by PHP.
|
||||
*
|
||||
* Enabling the "create_new_console" option allows a subprocess to continue
|
||||
* to run after the main process exited, on both Windows and *nix
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
if ($this->isRunning()) {
|
||||
throw new RuntimeException('Setting options while the process is running is not possible.');
|
||||
}
|
||||
|
||||
$defaultOptions = $this->options;
|
||||
$existingOptions = ['blocking_pipes', 'create_process_group', 'create_new_console'];
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
if (!\in_array($key, $existingOptions)) {
|
||||
$this->options = $defaultOptions;
|
||||
throw new LogicException(sprintf('Invalid option "%s" passed to "%s()". Supported options are "%s".', $key, __METHOD__, implode('", "', $existingOptions)));
|
||||
}
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether TTY is supported on the current operating system.
|
||||
*/
|
||||
@@ -1303,30 +1308,26 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param callable|null $callback The user defined PHP callback
|
||||
*
|
||||
* @return \Closure A PHP closure
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function buildCallback(callable $callback = null)
|
||||
{
|
||||
if ($this->outputDisabled) {
|
||||
return function ($type, $data) use ($callback) {
|
||||
if (null !== $callback) {
|
||||
return $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 $callback($type, $data);
|
||||
}
|
||||
return null !== $callback && $callback($type, $data);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1335,7 +1336,7 @@ class Process implements \IteratorAggregate
|
||||
*
|
||||
* @param bool $blocking Whether to use a blocking read call
|
||||
*/
|
||||
protected function updateStatus($blocking)
|
||||
protected function updateStatus(bool $blocking)
|
||||
{
|
||||
if (self::STATUS_STARTED !== $this->status) {
|
||||
return;
|
||||
@@ -1371,9 +1372,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');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1475,8 +1476,8 @@ class Process implements \IteratorAggregate
|
||||
$this->exitcode = null;
|
||||
$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;
|
||||
@@ -1487,11 +1488,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
|
||||
@@ -1500,7 +1499,7 @@ class Process implements \IteratorAggregate
|
||||
{
|
||||
if (null === $pid = $this->getPid()) {
|
||||
if ($throwException) {
|
||||
throw new LogicException('Can not send signal on a non running process.');
|
||||
throw new LogicException('Cannot send signal on a non running process.');
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1540,7 +1539,7 @@ 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;
|
||||
@@ -1560,7 +1559,7 @@ 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")) {
|
||||
@@ -1594,7 +1593,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1606,7 +1605,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1621,7 +1620,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)) {
|
||||
@@ -1632,22 +1631,22 @@ class Process implements \IteratorAggregate
|
||||
return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"';
|
||||
}
|
||||
|
||||
private function getDefaultEnv()
|
||||
private function replacePlaceholders(string $commandline, array $env)
|
||||
{
|
||||
$env = [];
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/symfony/process/ProcessUtils.php
vendored
6
vendor/symfony/process/ProcessUtils.php
vendored
@@ -35,11 +35,11 @@ class ProcessUtils
|
||||
* @param string $caller The name of method call that validates the input
|
||||
* @param mixed $input The input to validate
|
||||
*
|
||||
* @return mixed The validated input
|
||||
* @return mixed
|
||||
*
|
||||
* @throws InvalidArgumentException In case the input is not valid
|
||||
*/
|
||||
public static function validateInput($caller, $input)
|
||||
public static function validateInput(string $caller, $input)
|
||||
{
|
||||
if (null !== $input) {
|
||||
if (\is_resource($input)) {
|
||||
@@ -61,7 +61,7 @@ class ProcessUtils
|
||||
return new \IteratorIterator($input);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('%s only accepts strings, Traversable objects or stream resources.', $caller));
|
||||
throw new InvalidArgumentException(sprintf('"%s" only accepts strings, Traversable objects or stream resources.', $caller));
|
||||
}
|
||||
|
||||
return $input;
|
||||
|
||||
25
vendor/symfony/process/README.md
vendored
25
vendor/symfony/process/README.md
vendored
@@ -3,11 +3,26 @@ Process Component
|
||||
|
||||
The Process component executes commands in sub-processes.
|
||||
|
||||
Sponsor
|
||||
-------
|
||||
|
||||
The Process component for Symfony 5.4/6.0 is [backed][1] by [SensioLabs][2].
|
||||
|
||||
As the creator of Symfony, SensioLabs supports companies using Symfony, with an
|
||||
offering encompassing consultancy, expertise, services, training, and technical
|
||||
assistance to ensure the success of web application development projects.
|
||||
|
||||
Help Symfony by [sponsoring][3] its development!
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* [Documentation](https://symfony.com/doc/current/components/process.html)
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
||||
* [Documentation](https://symfony.com/doc/current/components/process.html)
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
||||
|
||||
[1]: https://symfony.com/backers
|
||||
[2]: https://sensiolabs.com
|
||||
[3]: https://symfony.com/sponsor
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Process\Tests;
|
||||
|
||||
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
require \dirname(__DIR__).'/vendor/autoload.php';
|
||||
|
||||
list('e' => $php) = getopt('e:') + ['e' => 'php'];
|
||||
|
||||
try {
|
||||
$process = new Process("exec $php -r \"echo 'ready'; trigger_error('error', E_USER_ERROR);\"");
|
||||
$process->start();
|
||||
$process->setTimeout(0.5);
|
||||
while (false === strpos($process->getOutput(), 'ready')) {
|
||||
usleep(1000);
|
||||
}
|
||||
$process->signal(SIGSTOP);
|
||||
$process->wait();
|
||||
|
||||
return $process->getExitCode();
|
||||
} catch (ProcessTimedOutException $t) {
|
||||
echo $t->getMessage().PHP_EOL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Process\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
|
||||
/**
|
||||
* @author Chris Smith <chris@cs278.org>
|
||||
*/
|
||||
class ExecutableFinderTest extends TestCase
|
||||
{
|
||||
private $path;
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if ($this->path) {
|
||||
// Restore path if it was changed.
|
||||
putenv('PATH='.$this->path);
|
||||
}
|
||||
}
|
||||
|
||||
private function setPath($path)
|
||||
{
|
||||
$this->path = getenv('PATH');
|
||||
putenv('PATH='.$path);
|
||||
}
|
||||
|
||||
public function testFind()
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
|
||||
$this->setPath(\dirname(PHP_BINARY));
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
$result = $finder->find($this->getPhpBinaryName());
|
||||
|
||||
$this->assertSamePath(PHP_BINARY, $result);
|
||||
}
|
||||
|
||||
public function testFindWithDefault()
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
|
||||
$expected = 'defaultValue';
|
||||
|
||||
$this->setPath('');
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
$result = $finder->find('foo', $expected);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFindWithNullAsDefault()
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
|
||||
$this->setPath('');
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
|
||||
$result = $finder->find('foo');
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
public function testFindWithExtraDirs()
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
|
||||
$this->setPath('');
|
||||
|
||||
$extraDirs = [\dirname(PHP_BINARY)];
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
$result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);
|
||||
|
||||
$this->assertSamePath(PHP_BINARY, $result);
|
||||
}
|
||||
|
||||
public function testFindWithOpenBaseDir()
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$this->markTestSkipped('Cannot run test on windows');
|
||||
}
|
||||
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
|
||||
$this->iniSet('open_basedir', \dirname(PHP_BINARY).PATH_SEPARATOR.'/');
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
$result = $finder->find($this->getPhpBinaryName());
|
||||
|
||||
$this->assertSamePath(PHP_BINARY, $result);
|
||||
}
|
||||
|
||||
public function testFindProcessInOpenBasedir()
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$this->markTestSkipped('Cannot run test on windows');
|
||||
}
|
||||
|
||||
$this->setPath('');
|
||||
$this->iniSet('open_basedir', PHP_BINARY.PATH_SEPARATOR.'/');
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
$result = $finder->find($this->getPhpBinaryName(), false);
|
||||
|
||||
$this->assertSamePath(PHP_BINARY, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.4
|
||||
*/
|
||||
public function testFindBatchExecutableOnWindows()
|
||||
{
|
||||
if (ini_get('open_basedir')) {
|
||||
$this->markTestSkipped('Cannot test when open_basedir is set');
|
||||
}
|
||||
if ('\\' !== \DIRECTORY_SEPARATOR) {
|
||||
$this->markTestSkipped('Can be only tested on windows');
|
||||
}
|
||||
|
||||
$target = tempnam(sys_get_temp_dir(), 'example-windows-executable');
|
||||
|
||||
touch($target);
|
||||
touch($target.'.BAT');
|
||||
|
||||
$this->assertFalse(is_executable($target));
|
||||
|
||||
$this->setPath(sys_get_temp_dir());
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
$result = $finder->find(basename($target), false);
|
||||
|
||||
unlink($target);
|
||||
unlink($target.'.BAT');
|
||||
|
||||
$this->assertSamePath($target.'.BAT', $result);
|
||||
}
|
||||
|
||||
private function assertSamePath($expected, $tested)
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$this->assertEquals(strtolower($expected), strtolower($tested));
|
||||
} else {
|
||||
$this->assertEquals($expected, $tested);
|
||||
}
|
||||
}
|
||||
|
||||
private function getPhpBinaryName()
|
||||
{
|
||||
return basename(PHP_BINARY, '\\' === \DIRECTORY_SEPARATOR ? '.exe' : '');
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
$outputs = [
|
||||
'First iteration output',
|
||||
'Second iteration output',
|
||||
'One more iteration output',
|
||||
'This took more time',
|
||||
];
|
||||
|
||||
$iterationTime = 10000;
|
||||
|
||||
foreach ($outputs as $output) {
|
||||
usleep($iterationTime);
|
||||
$iterationTime *= 10;
|
||||
echo $output."\n";
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runs a PHP script that can be stopped only with a SIGKILL (9) signal for 3 seconds.
|
||||
*
|
||||
* @args duration Run this script with a custom duration
|
||||
*
|
||||
* @example `php NonStopableProcess.php 42` will run the script for 42 seconds
|
||||
*/
|
||||
function handleSignal($signal)
|
||||
{
|
||||
switch ($signal) {
|
||||
case SIGTERM:
|
||||
$name = 'SIGTERM';
|
||||
break;
|
||||
case SIGINT:
|
||||
$name = 'SIGINT';
|
||||
break;
|
||||
default:
|
||||
$name = $signal.' (unknown)';
|
||||
break;
|
||||
}
|
||||
|
||||
echo "signal $name\n";
|
||||
}
|
||||
|
||||
pcntl_signal(SIGTERM, 'handleSignal');
|
||||
pcntl_signal(SIGINT, 'handleSignal');
|
||||
|
||||
echo 'received ';
|
||||
|
||||
$duration = isset($argv[1]) ? (int) $argv[1] : 3;
|
||||
$start = microtime(true);
|
||||
|
||||
while ($duration > (microtime(true) - $start)) {
|
||||
usleep(10000);
|
||||
pcntl_signal_dispatch();
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Process\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
|
||||
/**
|
||||
* @author Robert Schönthal <seroscho@googlemail.com>
|
||||
*/
|
||||
class PhpExecutableFinderTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* tests find() with the constant PHP_BINARY.
|
||||
*/
|
||||
public function testFind()
|
||||
{
|
||||
$f = new PhpExecutableFinder();
|
||||
|
||||
$current = PHP_BINARY;
|
||||
$args = 'phpdbg' === \PHP_SAPI ? ' -qrr' : '';
|
||||
|
||||
$this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP');
|
||||
$this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
|
||||
}
|
||||
|
||||
/**
|
||||
* tests find() with the env var PHP_PATH.
|
||||
*/
|
||||
public function testFindArguments()
|
||||
{
|
||||
$f = new PhpExecutableFinder();
|
||||
|
||||
if ('phpdbg' === \PHP_SAPI) {
|
||||
$this->assertEquals($f->findArguments(), ['-qrr'], '::findArguments() returns phpdbg arguments');
|
||||
} else {
|
||||
$this->assertEquals($f->findArguments(), [], '::findArguments() returns no arguments');
|
||||
}
|
||||
}
|
||||
}
|
||||
63
vendor/symfony/process/Tests/PhpProcessTest.php
vendored
63
vendor/symfony/process/Tests/PhpProcessTest.php
vendored
@@ -1,63 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Process\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Process\PhpExecutableFinder;
|
||||
use Symfony\Component\Process\PhpProcess;
|
||||
|
||||
class PhpProcessTest extends TestCase
|
||||
{
|
||||
public function testNonBlockingWorks()
|
||||
{
|
||||
$expected = 'hello world!';
|
||||
$process = new PhpProcess(<<<PHP
|
||||
<?php echo '$expected';
|
||||
PHP
|
||||
);
|
||||
$process->start();
|
||||
$process->wait();
|
||||
$this->assertEquals($expected, $process->getOutput());
|
||||
}
|
||||
|
||||
public function testCommandLine()
|
||||
{
|
||||
$process = new PhpProcess(<<<'PHP'
|
||||
<?php echo phpversion().PHP_SAPI;
|
||||
PHP
|
||||
);
|
||||
|
||||
$commandLine = $process->getCommandLine();
|
||||
|
||||
$process->start();
|
||||
$this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start');
|
||||
|
||||
$process->wait();
|
||||
$this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait');
|
||||
|
||||
$this->assertSame(PHP_VERSION.\PHP_SAPI, $process->getOutput());
|
||||
}
|
||||
|
||||
public function testPassingPhpExplicitly()
|
||||
{
|
||||
$finder = new PhpExecutableFinder();
|
||||
$php = array_merge([$finder->find(false)], $finder->findArguments());
|
||||
|
||||
$expected = 'hello world!';
|
||||
$script = <<<PHP
|
||||
<?php echo '$expected';
|
||||
PHP;
|
||||
$process = new PhpProcess($script, null, null, 60, $php);
|
||||
$process->run();
|
||||
$this->assertEquals($expected, $process->getOutput());
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define('ERR_SELECT_FAILED', 1);
|
||||
define('ERR_TIMEOUT', 2);
|
||||
define('ERR_READ_FAILED', 3);
|
||||
define('ERR_WRITE_FAILED', 4);
|
||||
|
||||
$read = [STDIN];
|
||||
$write = [STDOUT, STDERR];
|
||||
|
||||
stream_set_blocking(STDIN, 0);
|
||||
stream_set_blocking(STDOUT, 0);
|
||||
stream_set_blocking(STDERR, 0);
|
||||
|
||||
$out = $err = '';
|
||||
while ($read || $write) {
|
||||
$r = $read;
|
||||
$w = $write;
|
||||
$e = null;
|
||||
$n = stream_select($r, $w, $e, 5);
|
||||
|
||||
if (false === $n) {
|
||||
die(ERR_SELECT_FAILED);
|
||||
} elseif ($n < 1) {
|
||||
die(ERR_TIMEOUT);
|
||||
}
|
||||
|
||||
if (in_array(STDOUT, $w) && strlen($out) > 0) {
|
||||
$written = fwrite(STDOUT, (string) $out, 32768);
|
||||
if (false === $written) {
|
||||
die(ERR_WRITE_FAILED);
|
||||
}
|
||||
$out = (string) substr($out, $written);
|
||||
}
|
||||
if (null === $read && '' === $out) {
|
||||
$write = array_diff($write, [STDOUT]);
|
||||
}
|
||||
|
||||
if (in_array(STDERR, $w) && strlen($err) > 0) {
|
||||
$written = fwrite(STDERR, (string) $err, 32768);
|
||||
if (false === $written) {
|
||||
die(ERR_WRITE_FAILED);
|
||||
}
|
||||
$err = (string) substr($err, $written);
|
||||
}
|
||||
if (null === $read && '' === $err) {
|
||||
$write = array_diff($write, [STDERR]);
|
||||
}
|
||||
|
||||
if ($r) {
|
||||
$str = fread(STDIN, 32768);
|
||||
if (false !== $str) {
|
||||
$out .= $str;
|
||||
$err .= $str;
|
||||
}
|
||||
if (false === $str || feof(STDIN)) {
|
||||
$read = null;
|
||||
if (!feof(STDIN)) {
|
||||
die(ERR_READ_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Process\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Process\Exception\ProcessFailedException;
|
||||
|
||||
/**
|
||||
* @author Sebastian Marek <proofek@gmail.com>
|
||||
*/
|
||||
class ProcessFailedExceptionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* tests ProcessFailedException throws exception if the process was successful.
|
||||
*/
|
||||
public function testProcessFailedExceptionThrowsException()
|
||||
{
|
||||
$process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(['isSuccessful'])->setConstructorArgs([['php']])->getMock();
|
||||
$process->expects($this->once())
|
||||
->method('isSuccessful')
|
||||
->willReturn(true);
|
||||
|
||||
if (method_exists($this, 'expectException')) {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Expected a failed process, but the given process was successful.');
|
||||
} else {
|
||||
$this->setExpectedException(\InvalidArgumentException::class, 'Expected a failed process, but the given process was successful.');
|
||||
}
|
||||
|
||||
new ProcessFailedException($process);
|
||||
}
|
||||
|
||||
/**
|
||||
* tests ProcessFailedException uses information from process output
|
||||
* to generate exception message.
|
||||
*/
|
||||
public function testProcessFailedExceptionPopulatesInformationFromProcessOutput()
|
||||
{
|
||||
$cmd = 'php';
|
||||
$exitCode = 1;
|
||||
$exitText = 'General error';
|
||||
$output = 'Command output';
|
||||
$errorOutput = 'FATAL: Unexpected error';
|
||||
$workingDirectory = getcwd();
|
||||
|
||||
$process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(['isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'])->setConstructorArgs([[$cmd]])->getMock();
|
||||
$process->expects($this->once())
|
||||
->method('isSuccessful')
|
||||
->willReturn(false);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getOutput')
|
||||
->willReturn($output);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getErrorOutput')
|
||||
->willReturn($errorOutput);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getExitCode')
|
||||
->willReturn($exitCode);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getExitCodeText')
|
||||
->willReturn($exitText);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('isOutputDisabled')
|
||||
->willReturn(false);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getWorkingDirectory')
|
||||
->willReturn($workingDirectory);
|
||||
|
||||
$exception = new ProcessFailedException($process);
|
||||
|
||||
$this->assertEquals(
|
||||
"The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
|
||||
str_replace("'php'", 'php', $exception->getMessage())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that ProcessFailedException does not extract information from
|
||||
* process output if it was previously disabled.
|
||||
*/
|
||||
public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
|
||||
{
|
||||
$cmd = 'php';
|
||||
$exitCode = 1;
|
||||
$exitText = 'General error';
|
||||
$workingDirectory = getcwd();
|
||||
|
||||
$process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(['isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'])->setConstructorArgs([[$cmd]])->getMock();
|
||||
$process->expects($this->once())
|
||||
->method('isSuccessful')
|
||||
->willReturn(false);
|
||||
|
||||
$process->expects($this->never())
|
||||
->method('getOutput');
|
||||
|
||||
$process->expects($this->never())
|
||||
->method('getErrorOutput');
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getExitCode')
|
||||
->willReturn($exitCode);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getExitCodeText')
|
||||
->willReturn($exitText);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('isOutputDisabled')
|
||||
->willReturn(true);
|
||||
|
||||
$process->expects($this->once())
|
||||
->method('getWorkingDirectory')
|
||||
->willReturn($workingDirectory);
|
||||
|
||||
$exception = new ProcessFailedException($process);
|
||||
|
||||
$this->assertEquals(
|
||||
"The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
|
||||
str_replace("'php'", 'php', $exception->getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
1557
vendor/symfony/process/Tests/ProcessTest.php
vendored
1557
vendor/symfony/process/Tests/ProcessTest.php
vendored
File diff suppressed because it is too large
Load Diff
21
vendor/symfony/process/Tests/SignalListener.php
vendored
21
vendor/symfony/process/Tests/SignalListener.php
vendored
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
pcntl_signal(SIGUSR1, function () { echo 'SIGUSR1'; exit; });
|
||||
|
||||
echo 'Caught ';
|
||||
|
||||
$n = 0;
|
||||
|
||||
while ($n++ < 400) {
|
||||
usleep(10000);
|
||||
pcntl_signal_dispatch();
|
||||
}
|
||||
12
vendor/symfony/process/composer.json
vendored
12
vendor/symfony/process/composer.json
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"type": "library",
|
||||
"description": "Symfony Process Component",
|
||||
"description": "Executes commands in sub-processes",
|
||||
"keywords": [],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
@@ -16,7 +16,8 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3"
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Component\\Process\\": "" },
|
||||
@@ -24,10 +25,5 @@
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.3-dev"
|
||||
}
|
||||
}
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
||||
30
vendor/symfony/process/phpunit.xml.dist
vendored
30
vendor/symfony/process/phpunit.xml.dist
vendored
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Symfony Process Component Test Suite">
|
||||
<directory>./Tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./</directory>
|
||||
<exclude>
|
||||
<directory>./Tests</directory>
|
||||
<directory>./vendor</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
Reference in New Issue
Block a user