Updated Symfony\Process
to version 6.5.2
This commit is contained in:
parent
28e673d5a4
commit
0f26bdc960
13 changed files with 207 additions and 252 deletions
|
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Updated `Symfony\polyfill-ctype` to version 1.27.0
|
- Updated `Symfony\polyfill-ctype` to version 1.27.0
|
||||||
- Updated `Symfony\polyfill-mbstring` to version 1.27.0
|
- Updated `Symfony\polyfill-mbstring` to version 1.27.0
|
||||||
- Updated `Symfony\polyfill-uuid` to version 1.27.0
|
- Updated `Symfony\polyfill-uuid` to version 1.27.0
|
||||||
|
- Updated `Symfony\Process` to version 6.2.5
|
||||||
|
|
||||||
## [1.0.1] - 2023-02-07
|
## [1.0.1] - 2023-02-07
|
||||||
|
|
||||||
|
|
12
src/ncc/ThirdParty/Symfony/Process/CHANGELOG.md
vendored
12
src/ncc/ThirdParty/Symfony/Process/CHANGELOG.md
vendored
|
@ -5,13 +5,13 @@ CHANGELOG
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* added `Process::setOptions()` to set `Process` specific options
|
* added `Process::setOptions()` to set `Process` specific options
|
||||||
* added option `create_new_console` to allow a subProcess to continue
|
* added option `create_new_console` to allow a subprocess to continue
|
||||||
to run after the main script exited, both on Linux and on Windows
|
to run after the main script exited, both on Linux and on Windows
|
||||||
|
|
||||||
5.1.0
|
5.1.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* added `Process::getStartTime()` to retrieve the start time of the Process as float
|
* added `Process::getStartTime()` to retrieve the start time of the process as float
|
||||||
|
|
||||||
5.0.0
|
5.0.0
|
||||||
-----
|
-----
|
||||||
|
@ -33,7 +33,7 @@ CHANGELOG
|
||||||
* added the `Process::fromShellCommandline()` to run commands in a shell wrapper
|
* added the `Process::fromShellCommandline()` to run commands in a shell wrapper
|
||||||
* deprecated passing a command as string when creating a `Process` instance
|
* deprecated passing a command as string when creating a `Process` instance
|
||||||
* deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods
|
* deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods
|
||||||
* added the `Process::waitUntil()` method to wait for the Process only for a
|
* added the `Process::waitUntil()` method to wait for the process only for a
|
||||||
specific output, then continue the normal execution of your application
|
specific output, then continue the normal execution of your application
|
||||||
|
|
||||||
4.1.0
|
4.1.0
|
||||||
|
@ -41,7 +41,7 @@ CHANGELOG
|
||||||
|
|
||||||
* added the `Process::isTtySupported()` method that allows to check for TTY support
|
* added the `Process::isTtySupported()` method that allows to check for TTY support
|
||||||
* made `PhpExecutableFinder` look for the `PHP_BINARY` env var when searching the php binary
|
* made `PhpExecutableFinder` look for the `PHP_BINARY` env var when searching the php binary
|
||||||
* added the `ProcessSignaledException` class to properly catch signaled Process errors
|
* added the `ProcessSignaledException` class to properly catch signaled process errors
|
||||||
|
|
||||||
4.0.0
|
4.0.0
|
||||||
-----
|
-----
|
||||||
|
@ -109,8 +109,8 @@ CHANGELOG
|
||||||
2.1.0
|
2.1.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* added support for non-blocking Processes (start(), wait(), isRunning(), stop())
|
* added support for non-blocking processes (start(), wait(), isRunning(), stop())
|
||||||
* enhanced Windows compatibility
|
* enhanced Windows compatibility
|
||||||
* added Process::getExitCodeText() that returns a string representation for
|
* added Process::getExitCodeText() that returns a string representation for
|
||||||
the exit code returned by the Process
|
the exit code returned by the process
|
||||||
* added ProcessBuilder
|
* added ProcessBuilder
|
||||||
|
|
|
@ -14,41 +14,41 @@ namespace ncc\ThirdParty\Symfony\Process\Exception;
|
||||||
use ncc\ThirdParty\Symfony\Process\Process;
|
use ncc\ThirdParty\Symfony\Process\Process;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception for failed Processes.
|
* Exception for failed processes.
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ProcessFailedException extends RuntimeException
|
class ProcessFailedException extends RuntimeException
|
||||||
{
|
{
|
||||||
private $Process;
|
private $process;
|
||||||
|
|
||||||
public function __construct(Process $Process)
|
public function __construct(Process $process)
|
||||||
{
|
{
|
||||||
if ($Process->isSuccessful()) {
|
if ($process->isSuccessful()) {
|
||||||
throw new InvalidArgumentException('Expected a failed Process, but the given Process was successful.');
|
throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
|
$error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
|
||||||
$Process->getCommandLine(),
|
$process->getCommandLine(),
|
||||||
$Process->getExitCode(),
|
$process->getExitCode(),
|
||||||
$Process->getExitCodeText(),
|
$process->getExitCodeText(),
|
||||||
$Process->getWorkingDirectory()
|
$process->getWorkingDirectory()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!$Process->isOutputDisabled()) {
|
if (!$process->isOutputDisabled()) {
|
||||||
$error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
|
$error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
|
||||||
$Process->getOutput(),
|
$process->getOutput(),
|
||||||
$Process->getErrorOutput()
|
$process->getErrorOutput()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($error);
|
parent::__construct($error);
|
||||||
|
|
||||||
$this->Process = $Process;
|
$this->process = $process;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProcess()
|
public function getProcess()
|
||||||
{
|
{
|
||||||
return $this->Process;
|
return $this->process;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,24 +14,24 @@ namespace ncc\ThirdParty\Symfony\Process\Exception;
|
||||||
use ncc\ThirdParty\Symfony\Process\Process;
|
use ncc\ThirdParty\Symfony\Process\Process;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception that is thrown when a Process has been signaled.
|
* Exception that is thrown when a process has been signaled.
|
||||||
*
|
*
|
||||||
* @author Sullivan Senechal <soullivaneuh@gmail.com>
|
* @author Sullivan Senechal <soullivaneuh@gmail.com>
|
||||||
*/
|
*/
|
||||||
final class ProcessSignaledException extends RuntimeException
|
final class ProcessSignaledException extends RuntimeException
|
||||||
{
|
{
|
||||||
private $Process;
|
private $process;
|
||||||
|
|
||||||
public function __construct(Process $Process)
|
public function __construct(Process $process)
|
||||||
{
|
{
|
||||||
$this->Process = $Process;
|
$this->process = $process;
|
||||||
|
|
||||||
parent::__construct(sprintf('The Process has been signaled with signal "%s".', $Process->getTermSignal()));
|
parent::__construct(sprintf('The process has been signaled with signal "%s".', $process->getTermSignal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProcess(): Process
|
public function getProcess(): Process
|
||||||
{
|
{
|
||||||
return $this->Process;
|
return $this->process;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSignal(): int
|
public function getSignal(): int
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace ncc\ThirdParty\Symfony\Process\Exception;
|
||||||
use ncc\ThirdParty\Symfony\Process\Process;
|
use ncc\ThirdParty\Symfony\Process\Process;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception that is thrown when a Process times out.
|
* Exception that is thrown when a process times out.
|
||||||
*
|
*
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -23,24 +23,24 @@ class ProcessTimedOutException extends RuntimeException
|
||||||
public const TYPE_GENERAL = 1;
|
public const TYPE_GENERAL = 1;
|
||||||
public const TYPE_IDLE = 2;
|
public const TYPE_IDLE = 2;
|
||||||
|
|
||||||
private $Process;
|
private $process;
|
||||||
private $timeoutType;
|
private $timeoutType;
|
||||||
|
|
||||||
public function __construct(Process $Process, int $timeoutType)
|
public function __construct(Process $process, int $timeoutType)
|
||||||
{
|
{
|
||||||
$this->Process = $Process;
|
$this->process = $process;
|
||||||
$this->timeoutType = $timeoutType;
|
$this->timeoutType = $timeoutType;
|
||||||
|
|
||||||
parent::__construct(sprintf(
|
parent::__construct(sprintf(
|
||||||
'The Process "%s" exceeded the timeout of %s seconds.',
|
'The process "%s" exceeded the timeout of %s seconds.',
|
||||||
$Process->getCommandLine(),
|
$process->getCommandLine(),
|
||||||
$this->getExceededTimeout()
|
$this->getExceededTimeout()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProcess()
|
public function getProcess()
|
||||||
{
|
{
|
||||||
return $this->Process;
|
return $this->process;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isGeneralTimeout()
|
public function isGeneralTimeout()
|
||||||
|
@ -56,8 +56,8 @@ class ProcessTimedOutException extends RuntimeException
|
||||||
public function getExceededTimeout()
|
public function getExceededTimeout()
|
||||||
{
|
{
|
||||||
return match ($this->timeoutType) {
|
return match ($this->timeoutType) {
|
||||||
self::TYPE_GENERAL => $this->Process->getTimeout(),
|
self::TYPE_GENERAL => $this->process->getTimeout(),
|
||||||
self::TYPE_IDLE => $this->Process->getIdleTimeout(),
|
self::TYPE_IDLE => $this->process->getIdleTimeout(),
|
||||||
default => throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)),
|
default => throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
2
src/ncc/ThirdParty/Symfony/Process/LICENSE
vendored
2
src/ncc/ThirdParty/Symfony/Process/LICENSE
vendored
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2004-2022 Fabien Potencier
|
Copyright (c) 2004-2023 Fabien Potencier
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -15,7 +15,7 @@ use ncc\ThirdParty\Symfony\Process\Exception\LogicException;
|
||||||
use ncc\ThirdParty\Symfony\Process\Exception\RuntimeException;
|
use ncc\ThirdParty\Symfony\Process\Exception\RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PhpProcess runs a PHP script in an independent Process.
|
* PhpProcess runs a PHP script in an independent process.
|
||||||
*
|
*
|
||||||
* $p = new PhpProcess('<?php echo "foo"; ?>');
|
* $p = new PhpProcess('<?php echo "foo"; ?>');
|
||||||
* $p->run();
|
* $p->run();
|
||||||
|
@ -27,8 +27,8 @@ class PhpProcess extends Process
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $script The PHP script to run (as a string)
|
* @param string $script The PHP script to run (as a string)
|
||||||
* @param string|null $cwd The working directory or null to use the working dir of the current PHP Process
|
* @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 array|null $env The environment variables or null to use the same environment as the current PHP process
|
||||||
* @param int $timeout The timeout in seconds
|
* @param int $timeout The timeout in seconds
|
||||||
* @param array|null $php Path to the PHP binary to use with any additional arguments
|
* @param array|null $php Path to the PHP binary to use with any additional arguments
|
||||||
*/
|
*/
|
||||||
|
@ -50,17 +50,11 @@ class PhpProcess extends Process
|
||||||
parent::__construct($php, $cwd, $env, $script, $timeout);
|
parent::__construct($php, $cwd, $env, $script, $timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, mixed $input = null, ?float $timeout = 60): static
|
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, mixed $input = null, ?float $timeout = 60): static
|
||||||
{
|
{
|
||||||
throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
|
throw new LogicException(sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function start(callable $callback = null, array $env = [])
|
public function start(callable $callback = null, array $env = [])
|
||||||
{
|
{
|
||||||
if (null === $this->getCommandLine()) {
|
if (null === $this->getCommandLine()) {
|
||||||
|
|
|
@ -41,9 +41,6 @@ abstract class AbstractPipes implements PipesInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
foreach ($this->pipes as $pipe) {
|
foreach ($this->pipes as $pipe) {
|
||||||
|
|
|
@ -50,9 +50,6 @@ class UnixPipes extends AbstractPipes
|
||||||
$this->close();
|
$this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getDescriptors(): array
|
public function getDescriptors(): array
|
||||||
{
|
{
|
||||||
if (!$this->haveReadSupport) {
|
if (!$this->haveReadSupport) {
|
||||||
|
@ -88,17 +85,11 @@ class UnixPipes extends AbstractPipes
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getFiles(): array
|
public function getFiles(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function readAndWrite(bool $blocking, bool $close = false): array
|
public function readAndWrite(bool $blocking, bool $close = false): array
|
||||||
{
|
{
|
||||||
$this->unblock();
|
$this->unblock();
|
||||||
|
@ -145,17 +136,11 @@ class UnixPipes extends AbstractPipes
|
||||||
return $read;
|
return $read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function haveReadSupport(): bool
|
public function haveReadSupport(): bool
|
||||||
{
|
{
|
||||||
return $this->haveReadSupport;
|
return $this->haveReadSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function areOpen(): bool
|
public function areOpen(): bool
|
||||||
{
|
{
|
||||||
return (bool) $this->pipes;
|
return (bool) $this->pipes;
|
||||||
|
|
|
@ -60,7 +60,7 @@ class WindowsPipes extends AbstractPipes
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
throw new RuntimeException('A temporary file could not be opened to write the Process output: '.$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;
|
continue 2;
|
||||||
|
@ -103,9 +103,6 @@ class WindowsPipes extends AbstractPipes
|
||||||
$this->close();
|
$this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getDescriptors(): array
|
public function getDescriptors(): array
|
||||||
{
|
{
|
||||||
if (!$this->haveReadSupport) {
|
if (!$this->haveReadSupport) {
|
||||||
|
@ -120,7 +117,7 @@ class WindowsPipes extends AbstractPipes
|
||||||
|
|
||||||
// We're not using pipe on Windows platform as it hangs (https://bugs.php.net/51800)
|
// 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
|
// 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
|
// So we redirect output within the commandline and pass the nul device to the process
|
||||||
return [
|
return [
|
||||||
['pipe', 'r'],
|
['pipe', 'r'],
|
||||||
['file', 'NUL', 'w'],
|
['file', 'NUL', 'w'],
|
||||||
|
@ -128,17 +125,11 @@ class WindowsPipes extends AbstractPipes
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getFiles(): array
|
public function getFiles(): array
|
||||||
{
|
{
|
||||||
return $this->files;
|
return $this->files;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function readAndWrite(bool $blocking, bool $close = false): array
|
public function readAndWrite(bool $blocking, bool $close = false): array
|
||||||
{
|
{
|
||||||
$this->unblock();
|
$this->unblock();
|
||||||
|
@ -171,25 +162,16 @@ class WindowsPipes extends AbstractPipes
|
||||||
return $read;
|
return $read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function haveReadSupport(): bool
|
public function haveReadSupport(): bool
|
||||||
{
|
{
|
||||||
return $this->haveReadSupport;
|
return $this->haveReadSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function areOpen(): bool
|
public function areOpen(): bool
|
||||||
{
|
{
|
||||||
return $this->pipes && $this->fileHandles;
|
return $this->pipes && $this->fileHandles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
parent::close();
|
parent::close();
|
||||||
|
|
328
src/ncc/ThirdParty/Symfony/Process/Process.php
vendored
328
src/ncc/ThirdParty/Symfony/Process/Process.php
vendored
|
@ -23,7 +23,7 @@ use ncc\ThirdParty\Symfony\Process\Pipes\WindowsPipes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process is a thin wrapper around proc_* functions to easily
|
* Process is a thin wrapper around proc_* functions to easily
|
||||||
* start independent PHP Processes.
|
* start independent PHP processes.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Romain Neutron <imprec@gmail.com>
|
* @author Romain Neutron <imprec@gmail.com>
|
||||||
|
@ -63,11 +63,11 @@ class Process implements \IteratorAggregate
|
||||||
private $idleTimeout;
|
private $idleTimeout;
|
||||||
private $exitcode;
|
private $exitcode;
|
||||||
private $fallbackStatus = [];
|
private $fallbackStatus = [];
|
||||||
private $ProcessInformation;
|
private $processInformation;
|
||||||
private $outputDisabled = false;
|
private $outputDisabled = false;
|
||||||
private $stdout;
|
private $stdout;
|
||||||
private $stderr;
|
private $stderr;
|
||||||
private $Process;
|
private $process;
|
||||||
private $status = self::STATUS_READY;
|
private $status = self::STATUS_READY;
|
||||||
private $incrementalOutputOffset = 0;
|
private $incrementalOutputOffset = 0;
|
||||||
private $incrementalErrorOutputOffset = 0;
|
private $incrementalErrorOutputOffset = 0;
|
||||||
|
@ -77,7 +77,7 @@ class Process implements \IteratorAggregate
|
||||||
|
|
||||||
private $useFileHandles = false;
|
private $useFileHandles = false;
|
||||||
/** @var PipesInterface */
|
/** @var PipesInterface */
|
||||||
private $ProcessPipes;
|
private $processPipes;
|
||||||
|
|
||||||
private $latestSignal;
|
private $latestSignal;
|
||||||
|
|
||||||
|
@ -114,12 +114,12 @@ class Process implements \IteratorAggregate
|
||||||
142 => 'Signal raised by alarm',
|
142 => 'Signal raised by alarm',
|
||||||
143 => 'Termination (request to terminate)',
|
143 => 'Termination (request to terminate)',
|
||||||
// 144 - not defined
|
// 144 - not defined
|
||||||
145 => 'Child Process terminated, stopped (or continued*)',
|
145 => 'Child process terminated, stopped (or continued*)',
|
||||||
146 => 'Continue if stopped',
|
146 => 'Continue if stopped',
|
||||||
147 => 'Stop executing temporarily',
|
147 => 'Stop executing temporarily',
|
||||||
148 => 'Terminal stop signal',
|
148 => 'Terminal stop signal',
|
||||||
149 => 'Background Process attempting to read from tty ("in")',
|
149 => 'Background process attempting to read from tty ("in")',
|
||||||
150 => 'Background Process attempting to write to tty ("out")',
|
150 => 'Background process attempting to write to tty ("out")',
|
||||||
151 => 'Urgent data available on socket',
|
151 => 'Urgent data available on socket',
|
||||||
152 => 'CPU time limit exceeded',
|
152 => 'CPU time limit exceeded',
|
||||||
153 => 'File size limit exceeded',
|
153 => 'File size limit exceeded',
|
||||||
|
@ -133,8 +133,8 @@ class Process implements \IteratorAggregate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $command The command to run and its arguments listed as separate entries
|
* @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 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 array|null $env The environment variables or null to use the same environment as the current PHP process
|
||||||
* @param mixed $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
|
* @param int|float|null $timeout The timeout in seconds or null to disable
|
||||||
*
|
*
|
||||||
|
@ -176,12 +176,12 @@ class Process implements \IteratorAggregate
|
||||||
* In order to inject dynamic values into command-lines, we strongly recommend using placeholders.
|
* 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:
|
* 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]);
|
* $process->run(null, ['MY_VAR' => $theValue]);
|
||||||
*
|
*
|
||||||
* @param string $command The command line to pass to the shell of the OS
|
* @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 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 array|null $env The environment variables or null to use the same environment as the current PHP process
|
||||||
* @param mixed $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
|
* @param int|float|null $timeout The timeout in seconds or null to disable
|
||||||
*
|
*
|
||||||
|
@ -189,10 +189,10 @@ class Process implements \IteratorAggregate
|
||||||
*/
|
*/
|
||||||
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, mixed $input = null, ?float $timeout = 60): static
|
public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, mixed $input = null, ?float $timeout = 60): static
|
||||||
{
|
{
|
||||||
$Process = new static([], $cwd, $env, $input, $timeout);
|
$process = new static([], $cwd, $env, $input, $timeout);
|
||||||
$Process->commandline = $command;
|
$process->commandline = $command;
|
||||||
|
|
||||||
return $Process;
|
return $process;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __sleep(): array
|
public function __sleep(): array
|
||||||
|
@ -208,7 +208,7 @@ class Process implements \IteratorAggregate
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if ($this->options['create_new_console'] ?? false) {
|
if ($this->options['create_new_console'] ?? false) {
|
||||||
$this->ProcessPipes->close();
|
$this->processPipes->close();
|
||||||
} else {
|
} else {
|
||||||
$this->stop(0);
|
$this->stop(0);
|
||||||
}
|
}
|
||||||
|
@ -220,13 +220,13 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the Process.
|
* Runs the process.
|
||||||
*
|
*
|
||||||
* The callback receives the type of output (out or err) and
|
* The callback receives the type of output (out or err) and
|
||||||
* some bytes from the output in real-time. It allows to have feedback
|
* some bytes from the output in real-time. It allows to have feedback
|
||||||
* from the independent Process during execution.
|
* from the independent process during execution.
|
||||||
*
|
*
|
||||||
* The STDOUT and STDERR are also available after the Process is finished
|
* The STDOUT and STDERR are also available after the process is finished
|
||||||
* via the getOutput() and getErrorOutput() methods.
|
* via the getOutput() and getErrorOutput() methods.
|
||||||
*
|
*
|
||||||
* @param callable|null $callback A PHP callback to run whenever there is some
|
* @param callable|null $callback A PHP callback to run whenever there is some
|
||||||
|
@ -234,10 +234,10 @@ class Process implements \IteratorAggregate
|
||||||
*
|
*
|
||||||
* @return int The exit status code
|
* @return int The exit status code
|
||||||
*
|
*
|
||||||
* @throws RuntimeException When Process can't be launched
|
* @throws RuntimeException When process can't be launched
|
||||||
* @throws RuntimeException When Process is already running
|
* @throws RuntimeException When process is already running
|
||||||
* @throws ProcessTimedOutException When Process timed out
|
* @throws ProcessTimedOutException When process timed out
|
||||||
* @throws ProcessSignaledException When Process stopped after receiving signal
|
* @throws ProcessSignaledException When process stopped after receiving signal
|
||||||
* @throws LogicException In case a callback is provided and output has been disabled
|
* @throws LogicException In case a callback is provided and output has been disabled
|
||||||
*
|
*
|
||||||
* @final
|
* @final
|
||||||
|
@ -250,14 +250,14 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the Process.
|
* Runs the process.
|
||||||
*
|
*
|
||||||
* This is identical to run() except that an exception is thrown if the Process
|
* This is identical to run() except that an exception is thrown if the process
|
||||||
* exits with a non-zero exit code.
|
* exits with a non-zero exit code.
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws ProcessFailedException if the Process didn't terminate successfully
|
* @throws ProcessFailedException if the process didn't terminate successfully
|
||||||
*
|
*
|
||||||
* @final
|
* @final
|
||||||
*/
|
*/
|
||||||
|
@ -271,22 +271,22 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the Process and returns after writing the input to STDIN.
|
* Starts the process and returns after writing the input to STDIN.
|
||||||
*
|
*
|
||||||
* This method blocks until all STDIN data is sent to the Process then it
|
* This method blocks until all STDIN data is sent to the process then it
|
||||||
* returns while the Process runs in the background.
|
* returns while the process runs in the background.
|
||||||
*
|
*
|
||||||
* The termination of the Process can be awaited with wait().
|
* The termination of the process can be awaited with wait().
|
||||||
*
|
*
|
||||||
* The callback receives the type of output (out or err) and some bytes from
|
* The callback receives the type of output (out or err) and some bytes from
|
||||||
* the output in real-time while writing the standard input to the Process.
|
* the output in real-time while writing the standard input to the process.
|
||||||
* It allows to have feedback from the independent Process during execution.
|
* It allows to have feedback from the independent process during execution.
|
||||||
*
|
*
|
||||||
* @param callable|null $callback A PHP callback to run whenever there is some
|
* @param callable|null $callback A PHP callback to run whenever there is some
|
||||||
* output available on STDOUT or STDERR
|
* output available on STDOUT or STDERR
|
||||||
*
|
*
|
||||||
* @throws RuntimeException When Process can't be launched
|
* @throws RuntimeException When process can't be launched
|
||||||
* @throws RuntimeException When Process is already running
|
* @throws RuntimeException When process is already running
|
||||||
* @throws LogicException In case a callback is provided and output has been disabled
|
* @throws LogicException In case a callback is provided and output has been disabled
|
||||||
*/
|
*/
|
||||||
public function start(callable $callback = null, array $env = [])
|
public function start(callable $callback = null, array $env = [])
|
||||||
|
@ -311,7 +311,7 @@ class Process implements \IteratorAggregate
|
||||||
$commandline = implode(' ', array_map($this->escapeArgument(...), $commandline));
|
$commandline = implode(' ', array_map($this->escapeArgument(...), $commandline));
|
||||||
|
|
||||||
if ('\\' !== \DIRECTORY_SEPARATOR) {
|
if ('\\' !== \DIRECTORY_SEPARATOR) {
|
||||||
// exec is mandatory to deal with sending a signal to the Process
|
// exec is mandatory to deal with sending a signal to the process
|
||||||
$commandline = 'exec '.$commandline;
|
$commandline = 'exec '.$commandline;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,7 +324,7 @@ class Process implements \IteratorAggregate
|
||||||
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
|
// last exit code is output on the fourth pipe and caught to work around --enable-sigchild
|
||||||
$descriptors[3] = ['pipe', 'w'];
|
$descriptors[3] = ['pipe', 'w'];
|
||||||
|
|
||||||
// See https://unix.stackexchange.com/questions/71205/background-Process-pipe-input
|
// See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
|
||||||
$commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
|
$commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
|
||||||
$commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
|
$commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
|
||||||
|
|
||||||
|
@ -344,15 +344,15 @@ class Process implements \IteratorAggregate
|
||||||
throw new RuntimeException(sprintf('The provided cwd "%s" does not exist.', $this->cwd));
|
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, $this->options);
|
$this->process = @proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options);
|
||||||
|
|
||||||
if (!\is_resource($this->Process)) {
|
if (!\is_resource($this->process)) {
|
||||||
throw new RuntimeException('Unable to launch a new Process.');
|
throw new RuntimeException('Unable to launch a new process.');
|
||||||
}
|
}
|
||||||
$this->status = self::STATUS_STARTED;
|
$this->status = self::STATUS_STARTED;
|
||||||
|
|
||||||
if (isset($descriptors[3])) {
|
if (isset($descriptors[3])) {
|
||||||
$this->fallbackStatus['pid'] = (int) fgets($this->ProcessPipes->pipes[3]);
|
$this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->tty) {
|
if ($this->tty) {
|
||||||
|
@ -364,15 +364,15 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restarts the Process.
|
* Restarts the process.
|
||||||
*
|
*
|
||||||
* Be warned that the Process is cloned before being started.
|
* Be warned that the process is cloned before being started.
|
||||||
*
|
*
|
||||||
* @param callable|null $callback A PHP callback to run whenever there is some
|
* @param callable|null $callback A PHP callback to run whenever there is some
|
||||||
* output available on STDOUT or STDERR
|
* output available on STDOUT or STDERR
|
||||||
*
|
*
|
||||||
* @throws RuntimeException When Process can't be launched
|
* @throws RuntimeException When process can't be launched
|
||||||
* @throws RuntimeException When Process is already running
|
* @throws RuntimeException When process is already running
|
||||||
*
|
*
|
||||||
* @see start()
|
* @see start()
|
||||||
*
|
*
|
||||||
|
@ -384,26 +384,26 @@ class Process implements \IteratorAggregate
|
||||||
throw new RuntimeException('Process is already running.');
|
throw new RuntimeException('Process is already running.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$Process = clone $this;
|
$process = clone $this;
|
||||||
$Process->start($callback, $env);
|
$process->start($callback, $env);
|
||||||
|
|
||||||
return $Process;
|
return $process;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for the Process to terminate.
|
* Waits for the process to terminate.
|
||||||
*
|
*
|
||||||
* The callback receives the type of output (out or err) and some bytes
|
* The callback receives the type of output (out or err) and some bytes
|
||||||
* from the output in real-time while writing the standard input to the Process.
|
* 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.
|
* It allows to have feedback from the independent process during execution.
|
||||||
*
|
*
|
||||||
* @param callable|null $callback A valid PHP callback
|
* @param callable|null $callback A valid PHP callback
|
||||||
*
|
*
|
||||||
* @return int The exitcode of the Process
|
* @return int The exitcode of the process
|
||||||
*
|
*
|
||||||
* @throws ProcessTimedOutException When Process timed out
|
* @throws ProcessTimedOutException When process timed out
|
||||||
* @throws ProcessSignaledException When Process stopped after receiving signal
|
* @throws ProcessSignaledException When process stopped after receiving signal
|
||||||
* @throws LogicException When Process is not yet started
|
* @throws LogicException When process is not yet started
|
||||||
*/
|
*/
|
||||||
public function wait(callable $callback = null): int
|
public function wait(callable $callback = null): int
|
||||||
{
|
{
|
||||||
|
@ -412,7 +412,7 @@ class Process implements \IteratorAggregate
|
||||||
$this->updateStatus(false);
|
$this->updateStatus(false);
|
||||||
|
|
||||||
if (null !== $callback) {
|
if (null !== $callback) {
|
||||||
if (!$this->ProcessPipes->haveReadSupport()) {
|
if (!$this->processPipes->haveReadSupport()) {
|
||||||
$this->stop(0);
|
$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".');
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ class Process implements \IteratorAggregate
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$this->checkTimeout();
|
$this->checkTimeout();
|
||||||
$running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->ProcessPipes->areOpen();
|
$running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
|
||||||
$this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
|
$this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
|
||||||
} while ($running);
|
} while ($running);
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ class Process implements \IteratorAggregate
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->ProcessInformation['signaled'] && $this->ProcessInformation['termsig'] !== $this->latestSignal) {
|
if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
|
||||||
throw new ProcessSignaledException($this);
|
throw new ProcessSignaledException($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,11 +441,11 @@ class Process implements \IteratorAggregate
|
||||||
* Waits until the callback returns true.
|
* Waits until the callback returns true.
|
||||||
*
|
*
|
||||||
* The callback receives the type of output (out or err) and some bytes
|
* The callback receives the type of output (out or err) and some bytes
|
||||||
* from the output in real-time while writing the standard input to the Process.
|
* 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.
|
* It allows to have feedback from the independent process during execution.
|
||||||
*
|
*
|
||||||
* @throws RuntimeException When Process timed out
|
* @throws RuntimeException When process timed out
|
||||||
* @throws LogicException When Process is not yet started
|
* @throws LogicException When process is not yet started
|
||||||
* @throws ProcessTimedOutException In case the timeout was reached
|
* @throws ProcessTimedOutException In case the timeout was reached
|
||||||
*/
|
*/
|
||||||
public function waitUntil(callable $callback): bool
|
public function waitUntil(callable $callback): bool
|
||||||
|
@ -453,7 +453,7 @@ class Process implements \IteratorAggregate
|
||||||
$this->requireProcessIsStarted(__FUNCTION__);
|
$this->requireProcessIsStarted(__FUNCTION__);
|
||||||
$this->updateStatus(false);
|
$this->updateStatus(false);
|
||||||
|
|
||||||
if (!$this->ProcessPipes->haveReadSupport()) {
|
if (!$this->processPipes->haveReadSupport()) {
|
||||||
$this->stop(0);
|
$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".');
|
||||||
}
|
}
|
||||||
|
@ -462,8 +462,8 @@ class Process implements \IteratorAggregate
|
||||||
$ready = false;
|
$ready = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
$this->checkTimeout();
|
$this->checkTimeout();
|
||||||
$running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->ProcessPipes->areOpen();
|
$running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
|
||||||
$output = $this->ProcessPipes->readAndWrite($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
|
$output = $this->processPipes->readAndWrite($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
|
||||||
|
|
||||||
foreach ($output as $type => $data) {
|
foreach ($output as $type => $data) {
|
||||||
if (3 !== $type) {
|
if (3 !== $type) {
|
||||||
|
@ -484,24 +484,24 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Pid (Process identifier), if applicable.
|
* Returns the Pid (process identifier), if applicable.
|
||||||
*
|
*
|
||||||
* @return int|null The Process id if running, null otherwise
|
* @return int|null The process id if running, null otherwise
|
||||||
*/
|
*/
|
||||||
public function getPid(): ?int
|
public function getPid(): ?int
|
||||||
{
|
{
|
||||||
return $this->isRunning() ? $this->ProcessInformation['pid'] : null;
|
return $this->isRunning() ? $this->processInformation['pid'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a POSIX signal to the Process.
|
* Sends a POSIX signal to the process.
|
||||||
*
|
*
|
||||||
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
|
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the Process is not running
|
* @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 --enable-sigchild is activated and the process can't be killed
|
||||||
* @throws RuntimeException In case of failure
|
* @throws RuntimeException In case of failure
|
||||||
*/
|
*/
|
||||||
public function signal(int $signal): static
|
public function signal(int $signal): static
|
||||||
|
@ -512,17 +512,17 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables fetching output and error output from the underlying Process.
|
* Disables fetching output and error output from the underlying process.
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws RuntimeException In case the Process is already running
|
* @throws RuntimeException In case the process is already running
|
||||||
* @throws LogicException if an idle timeout is set
|
* @throws LogicException if an idle timeout is set
|
||||||
*/
|
*/
|
||||||
public function disableOutput(): static
|
public function disableOutput(): static
|
||||||
{
|
{
|
||||||
if ($this->isRunning()) {
|
if ($this->isRunning()) {
|
||||||
throw new RuntimeException('Disabling output while the Process is running is not possible.');
|
throw new RuntimeException('Disabling output while the process is running is not possible.');
|
||||||
}
|
}
|
||||||
if (null !== $this->idleTimeout) {
|
if (null !== $this->idleTimeout) {
|
||||||
throw new LogicException('Output cannot be disabled while an idle timeout is set.');
|
throw new LogicException('Output cannot be disabled while an idle timeout is set.');
|
||||||
|
@ -534,16 +534,16 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables fetching output and error output from the underlying Process.
|
* Enables fetching output and error output from the underlying process.
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws RuntimeException In case the Process is already running
|
* @throws RuntimeException In case the process is already running
|
||||||
*/
|
*/
|
||||||
public function enableOutput(): static
|
public function enableOutput(): static
|
||||||
{
|
{
|
||||||
if ($this->isRunning()) {
|
if ($this->isRunning()) {
|
||||||
throw new RuntimeException('Enabling output while the Process is running is not possible.');
|
throw new RuntimeException('Enabling output while the process is running is not possible.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->outputDisabled = false;
|
$this->outputDisabled = false;
|
||||||
|
@ -560,10 +560,10 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current output of the Process (STDOUT).
|
* Returns the current output of the process (STDOUT).
|
||||||
*
|
*
|
||||||
* @throws LogicException in case the output has been disabled
|
* @throws LogicException in case the output has been disabled
|
||||||
* @throws LogicException In case the Process is not started
|
* @throws LogicException In case the process is not started
|
||||||
*/
|
*/
|
||||||
public function getOutput(): string
|
public function getOutput(): string
|
||||||
{
|
{
|
||||||
|
@ -583,7 +583,7 @@ class Process implements \IteratorAggregate
|
||||||
* output, this one returns the new output since the last call.
|
* output, this one returns the new output since the last call.
|
||||||
*
|
*
|
||||||
* @throws LogicException in case the output has been disabled
|
* @throws LogicException in case the output has been disabled
|
||||||
* @throws LogicException In case the Process is not started
|
* @throws LogicException In case the process is not started
|
||||||
*/
|
*/
|
||||||
public function getIncrementalOutput(): string
|
public function getIncrementalOutput(): string
|
||||||
{
|
{
|
||||||
|
@ -600,12 +600,12 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an iterator to the output of the Process, with the output type as keys (Process::OUT/ERR).
|
* Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR).
|
||||||
*
|
*
|
||||||
* @param int $flags A bit field of Process::ITER_* flags
|
* @param int $flags A bit field of Process::ITER_* flags
|
||||||
*
|
*
|
||||||
* @throws LogicException in case the output has been disabled
|
* @throws LogicException in case the output has been disabled
|
||||||
* @throws LogicException In case the Process is not started
|
* @throws LogicException In case the process is not started
|
||||||
*/
|
*/
|
||||||
public function getIterator(int $flags = 0): \Generator
|
public function getIterator(int $flags = 0): \Generator
|
||||||
{
|
{
|
||||||
|
@ -655,7 +655,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the Process output.
|
* Clears the process output.
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
|
@ -669,10 +669,10 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current error output of the Process (STDERR).
|
* Returns the current error output of the process (STDERR).
|
||||||
*
|
*
|
||||||
* @throws LogicException in case the output has been disabled
|
* @throws LogicException in case the output has been disabled
|
||||||
* @throws LogicException In case the Process is not started
|
* @throws LogicException In case the process is not started
|
||||||
*/
|
*/
|
||||||
public function getErrorOutput(): string
|
public function getErrorOutput(): string
|
||||||
{
|
{
|
||||||
|
@ -693,7 +693,7 @@ class Process implements \IteratorAggregate
|
||||||
* call.
|
* call.
|
||||||
*
|
*
|
||||||
* @throws LogicException in case the output has been disabled
|
* @throws LogicException in case the output has been disabled
|
||||||
* @throws LogicException In case the Process is not started
|
* @throws LogicException In case the process is not started
|
||||||
*/
|
*/
|
||||||
public function getIncrementalErrorOutput(): string
|
public function getIncrementalErrorOutput(): string
|
||||||
{
|
{
|
||||||
|
@ -710,7 +710,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the Process output.
|
* Clears the process output.
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
|
@ -724,7 +724,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the exit code returned by the Process.
|
* Returns the exit code returned by the process.
|
||||||
*
|
*
|
||||||
* @return int|null The exit status code, null if the Process is not terminated
|
* @return int|null The exit status code, null if the Process is not terminated
|
||||||
*/
|
*/
|
||||||
|
@ -736,7 +736,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representation for the exit code returned by the Process.
|
* Returns a string representation for the exit code returned by the process.
|
||||||
*
|
*
|
||||||
* This method relies on the Unix exit code status standardization
|
* This method relies on the Unix exit code status standardization
|
||||||
* and might not be relevant for other operating systems.
|
* and might not be relevant for other operating systems.
|
||||||
|
@ -756,7 +756,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the Process ended successfully.
|
* Checks if the process ended successfully.
|
||||||
*/
|
*/
|
||||||
public function isSuccessful(): bool
|
public function isSuccessful(): bool
|
||||||
{
|
{
|
||||||
|
@ -764,68 +764,68 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the child Process has been terminated by an uncaught signal.
|
* Returns true if the child process has been terminated by an uncaught signal.
|
||||||
*
|
*
|
||||||
* It always returns false on Windows.
|
* It always returns false on Windows.
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the Process is not terminated
|
* @throws LogicException In case the process is not terminated
|
||||||
*/
|
*/
|
||||||
public function hasBeenSignaled(): bool
|
public function hasBeenSignaled(): bool
|
||||||
{
|
{
|
||||||
$this->requireProcessIsTerminated(__FUNCTION__);
|
$this->requireProcessIsTerminated(__FUNCTION__);
|
||||||
|
|
||||||
return $this->ProcessInformation['signaled'];
|
return $this->processInformation['signaled'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of the signal that caused the child Process to terminate its execution.
|
* Returns the number of the signal that caused the child process to terminate its execution.
|
||||||
*
|
*
|
||||||
* It is only meaningful if hasBeenSignaled() returns true.
|
* It is only meaningful if hasBeenSignaled() returns true.
|
||||||
*
|
*
|
||||||
* @throws RuntimeException In case --enable-sigchild is activated
|
* @throws RuntimeException In case --enable-sigchild is activated
|
||||||
* @throws LogicException In case the Process is not terminated
|
* @throws LogicException In case the process is not terminated
|
||||||
*/
|
*/
|
||||||
public function getTermSignal(): int
|
public function getTermSignal(): int
|
||||||
{
|
{
|
||||||
$this->requireProcessIsTerminated(__FUNCTION__);
|
$this->requireProcessIsTerminated(__FUNCTION__);
|
||||||
|
|
||||||
if ($this->isSigchildEnabled() && -1 === $this->ProcessInformation['termsig']) {
|
if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) {
|
||||||
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal cannot be retrieved.');
|
throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal cannot be retrieved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->ProcessInformation['termsig'];
|
return $this->processInformation['termsig'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the child Process has been stopped by a signal.
|
* Returns true if the child process has been stopped by a signal.
|
||||||
*
|
*
|
||||||
* It always returns false on Windows.
|
* It always returns false on Windows.
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the Process is not terminated
|
* @throws LogicException In case the process is not terminated
|
||||||
*/
|
*/
|
||||||
public function hasBeenStopped(): bool
|
public function hasBeenStopped(): bool
|
||||||
{
|
{
|
||||||
$this->requireProcessIsTerminated(__FUNCTION__);
|
$this->requireProcessIsTerminated(__FUNCTION__);
|
||||||
|
|
||||||
return $this->ProcessInformation['stopped'];
|
return $this->processInformation['stopped'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of the signal that caused the child Process to stop its execution.
|
* Returns the number of the signal that caused the child process to stop its execution.
|
||||||
*
|
*
|
||||||
* It is only meaningful if hasBeenStopped() returns true.
|
* It is only meaningful if hasBeenStopped() returns true.
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the Process is not terminated
|
* @throws LogicException In case the process is not terminated
|
||||||
*/
|
*/
|
||||||
public function getStopSignal(): int
|
public function getStopSignal(): int
|
||||||
{
|
{
|
||||||
$this->requireProcessIsTerminated(__FUNCTION__);
|
$this->requireProcessIsTerminated(__FUNCTION__);
|
||||||
|
|
||||||
return $this->ProcessInformation['stopsig'];
|
return $this->processInformation['stopsig'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the Process is currently running.
|
* Checks if the process is currently running.
|
||||||
*/
|
*/
|
||||||
public function isRunning(): bool
|
public function isRunning(): bool
|
||||||
{
|
{
|
||||||
|
@ -835,11 +835,11 @@ class Process implements \IteratorAggregate
|
||||||
|
|
||||||
$this->updateStatus(false);
|
$this->updateStatus(false);
|
||||||
|
|
||||||
return $this->ProcessInformation['running'];
|
return $this->processInformation['running'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the Process has been started with no regard to the current state.
|
* Checks if the process has been started with no regard to the current state.
|
||||||
*/
|
*/
|
||||||
public function isStarted(): bool
|
public function isStarted(): bool
|
||||||
{
|
{
|
||||||
|
@ -847,7 +847,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the Process is terminated.
|
* Checks if the process is terminated.
|
||||||
*/
|
*/
|
||||||
public function isTerminated(): bool
|
public function isTerminated(): bool
|
||||||
{
|
{
|
||||||
|
@ -857,7 +857,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Process status.
|
* Gets the process status.
|
||||||
*
|
*
|
||||||
* The status is one of: ready, started, terminated.
|
* The status is one of: ready, started, terminated.
|
||||||
*/
|
*/
|
||||||
|
@ -869,12 +869,12 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the Process.
|
* Stops the process.
|
||||||
*
|
*
|
||||||
* @param int|float $timeout The timeout in seconds
|
* @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)
|
* @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
|
||||||
*
|
*
|
||||||
* @return int|null The exit-code of the Process or null if it's not running
|
* @return int|null The exit-code of the process or null if it's not running
|
||||||
*/
|
*/
|
||||||
public function stop(float $timeout = 10, int $signal = null): ?int
|
public function stop(float $timeout = 10, int $signal = null): ?int
|
||||||
{
|
{
|
||||||
|
@ -887,7 +887,7 @@ class Process implements \IteratorAggregate
|
||||||
} while ($this->isRunning() && microtime(true) < $timeoutMicro);
|
} while ($this->isRunning() && microtime(true) < $timeoutMicro);
|
||||||
|
|
||||||
if ($this->isRunning()) {
|
if ($this->isRunning()) {
|
||||||
// Avoid exception here: Process is supposed to be running, but it might have stopped just
|
// Avoid exception here: process is supposed to be running, but it might have stopped just
|
||||||
// after this line. In any case, let's silently discard the error, we cannot do anything.
|
// after this line. In any case, let's silently discard the error, we cannot do anything.
|
||||||
$this->doSignal($signal ?: 9, false);
|
$this->doSignal($signal ?: 9, false);
|
||||||
}
|
}
|
||||||
|
@ -950,7 +950,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Process timeout in seconds (max. runtime).
|
* Gets the process timeout in seconds (max. runtime).
|
||||||
*/
|
*/
|
||||||
public function getTimeout(): ?float
|
public function getTimeout(): ?float
|
||||||
{
|
{
|
||||||
|
@ -958,7 +958,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Process idle timeout in seconds (max. time since last output).
|
* Gets the process idle timeout in seconds (max. time since last output).
|
||||||
*/
|
*/
|
||||||
public function getIdleTimeout(): ?float
|
public function getIdleTimeout(): ?float
|
||||||
{
|
{
|
||||||
|
@ -966,7 +966,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Process timeout (max. runtime) in seconds.
|
* Sets the process timeout (max. runtime) in seconds.
|
||||||
*
|
*
|
||||||
* To disable the timeout, set this value to null.
|
* To disable the timeout, set this value to null.
|
||||||
*
|
*
|
||||||
|
@ -982,7 +982,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Process idle timeout (max. time since last output) in seconds.
|
* Sets the process idle timeout (max. time since last output) in seconds.
|
||||||
*
|
*
|
||||||
* To disable the timeout, set this value to null.
|
* To disable the timeout, set this value to null.
|
||||||
*
|
*
|
||||||
|
@ -1113,18 +1113,18 @@ class Process implements \IteratorAggregate
|
||||||
/**
|
/**
|
||||||
* Sets the input.
|
* Sets the input.
|
||||||
*
|
*
|
||||||
* This content will be passed to the underlying Process standard input.
|
* This content will be passed to the underlying process standard input.
|
||||||
*
|
*
|
||||||
* @param string|int|float|bool|resource|\Traversable|null $input The content
|
* @param string|int|float|bool|resource|\Traversable|null $input The content
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the Process is running
|
* @throws LogicException In case the process is running
|
||||||
*/
|
*/
|
||||||
public function setInput(mixed $input): static
|
public function setInput(mixed $input): static
|
||||||
{
|
{
|
||||||
if ($this->isRunning()) {
|
if ($this->isRunning()) {
|
||||||
throw new LogicException('Input cannot 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);
|
$this->input = ProcessUtils::validateInput(__METHOD__, $input);
|
||||||
|
@ -1133,10 +1133,10 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a check between the timeout definition and the time the Process started.
|
* Performs a check between the timeout definition and the time the process started.
|
||||||
*
|
*
|
||||||
* In case you run a background Process (with the start method), you should
|
* In case you run a background process (with the start method), you should
|
||||||
* trigger this method regularly to ensure the Process timeout
|
* trigger this method regularly to ensure the process timeout
|
||||||
*
|
*
|
||||||
* @throws ProcessTimedOutException In case the timeout was reached
|
* @throws ProcessTimedOutException In case the timeout was reached
|
||||||
*/
|
*/
|
||||||
|
@ -1160,12 +1160,12 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws LogicException in case Process is not started
|
* @throws LogicException in case process is not started
|
||||||
*/
|
*/
|
||||||
public function getStartTime(): float
|
public function getStartTime(): float
|
||||||
{
|
{
|
||||||
if (!$this->isStarted()) {
|
if (!$this->isStarted()) {
|
||||||
throw new LogicException('Start time is only available after Process start.');
|
throw new LogicException('Start time is only available after process start.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->starttime;
|
return $this->starttime;
|
||||||
|
@ -1176,17 +1176,17 @@ class Process implements \IteratorAggregate
|
||||||
*
|
*
|
||||||
* @see https://php.net/proc_open for the options supported by PHP.
|
* @see https://php.net/proc_open for the options supported by PHP.
|
||||||
*
|
*
|
||||||
* Enabling the "create_new_console" option allows a subProcess to continue
|
* Enabling the "create_new_console" option allows a subprocess to continue
|
||||||
* to run after the main Process exited, on both Windows and *nix
|
* to run after the main process exited, on both Windows and *nix
|
||||||
*/
|
*/
|
||||||
public function setOptions(array $options)
|
public function setOptions(array $options)
|
||||||
{
|
{
|
||||||
if ($this->isRunning()) {
|
if ($this->isRunning()) {
|
||||||
throw new RuntimeException('Setting options while the Process is running is not possible.');
|
throw new RuntimeException('Setting options while the process is running is not possible.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultOptions = $this->options;
|
$defaultOptions = $this->options;
|
||||||
$existingOptions = ['blocking_pipes', 'create_Process_group', 'create_new_console'];
|
$existingOptions = ['blocking_pipes', 'create_process_group', 'create_new_console'];
|
||||||
|
|
||||||
foreach ($options as $key => $value) {
|
foreach ($options as $key => $value) {
|
||||||
if (!\in_array($key, $existingOptions)) {
|
if (!\in_array($key, $existingOptions)) {
|
||||||
|
@ -1204,11 +1204,7 @@ class Process implements \IteratorAggregate
|
||||||
{
|
{
|
||||||
static $isTtySupported;
|
static $isTtySupported;
|
||||||
|
|
||||||
if (null === $isTtySupported) {
|
return $isTtySupported ??= ('/' === \DIRECTORY_SEPARATOR && stream_isatty(\STDOUT));
|
||||||
$isTtySupported = (bool) @proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $isTtySupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1238,12 +1234,12 @@ class Process implements \IteratorAggregate
|
||||||
$this->input->rewind();
|
$this->input->rewind();
|
||||||
}
|
}
|
||||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||||
$this->ProcessPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback);
|
$this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback);
|
||||||
} else {
|
} else {
|
||||||
$this->ProcessPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback);
|
$this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->ProcessPipes->getDescriptors();
|
return $this->processPipes->getDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1276,7 +1272,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the status of the Process, reads pipes.
|
* Updates the status of the process, reads pipes.
|
||||||
*
|
*
|
||||||
* @param bool $blocking Whether to use a blocking read call
|
* @param bool $blocking Whether to use a blocking read call
|
||||||
*/
|
*/
|
||||||
|
@ -1286,13 +1282,13 @@ class Process implements \IteratorAggregate
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ProcessInformation = proc_get_status($this->Process);
|
$this->processInformation = proc_get_status($this->process);
|
||||||
$running = $this->ProcessInformation['running'];
|
$running = $this->processInformation['running'];
|
||||||
|
|
||||||
$this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running);
|
$this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running);
|
||||||
|
|
||||||
if ($this->fallbackStatus && $this->isSigchildEnabled()) {
|
if ($this->fallbackStatus && $this->isSigchildEnabled()) {
|
||||||
$this->ProcessInformation = $this->fallbackStatus + $this->ProcessInformation;
|
$this->processInformation = $this->fallbackStatus + $this->processInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$running) {
|
if (!$running) {
|
||||||
|
@ -1325,7 +1321,7 @@ class Process implements \IteratorAggregate
|
||||||
* @param string $caller The name of the method that needs fresh outputs
|
* @param string $caller The name of the method that needs fresh outputs
|
||||||
* @param bool $blocking Whether to use blocking calls or not
|
* @param bool $blocking Whether to use blocking calls or not
|
||||||
*
|
*
|
||||||
* @throws LogicException in case output has been disabled or Process is not started
|
* @throws LogicException in case output has been disabled or process is not started
|
||||||
*/
|
*/
|
||||||
private function readPipesForOutput(string $caller, bool $blocking = false)
|
private function readPipesForOutput(string $caller, bool $blocking = false)
|
||||||
{
|
{
|
||||||
|
@ -1364,7 +1360,7 @@ class Process implements \IteratorAggregate
|
||||||
*/
|
*/
|
||||||
private function readPipes(bool $blocking, bool $close)
|
private function readPipes(bool $blocking, bool $close)
|
||||||
{
|
{
|
||||||
$result = $this->ProcessPipes->readAndWrite($blocking, $close);
|
$result = $this->processPipes->readAndWrite($blocking, $close);
|
||||||
|
|
||||||
$callback = $this->callback;
|
$callback = $this->callback;
|
||||||
foreach ($result as $type => $data) {
|
foreach ($result as $type => $data) {
|
||||||
|
@ -1377,26 +1373,26 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes Process resource, closes file handles, sets the exitcode.
|
* Closes process resource, closes file handles, sets the exitcode.
|
||||||
*
|
*
|
||||||
* @return int The exitcode
|
* @return int The exitcode
|
||||||
*/
|
*/
|
||||||
private function close(): int
|
private function close(): int
|
||||||
{
|
{
|
||||||
$this->ProcessPipes->close();
|
$this->processPipes->close();
|
||||||
if (\is_resource($this->Process)) {
|
if (\is_resource($this->process)) {
|
||||||
proc_close($this->Process);
|
proc_close($this->process);
|
||||||
}
|
}
|
||||||
$this->exitcode = $this->ProcessInformation['exitcode'];
|
$this->exitcode = $this->processInformation['exitcode'];
|
||||||
$this->status = self::STATUS_TERMINATED;
|
$this->status = self::STATUS_TERMINATED;
|
||||||
|
|
||||||
if (-1 === $this->exitcode) {
|
if (-1 === $this->exitcode) {
|
||||||
if ($this->ProcessInformation['signaled'] && 0 < $this->ProcessInformation['termsig']) {
|
if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
|
||||||
// if Process has been signaled, no exitcode but a valid termsig, apply Unix convention
|
// if process has been signaled, no exitcode but a valid termsig, apply Unix convention
|
||||||
$this->exitcode = 128 + $this->ProcessInformation['termsig'];
|
$this->exitcode = 128 + $this->processInformation['termsig'];
|
||||||
} elseif ($this->isSigchildEnabled()) {
|
} elseif ($this->isSigchildEnabled()) {
|
||||||
$this->ProcessInformation['signaled'] = true;
|
$this->processInformation['signaled'] = true;
|
||||||
$this->ProcessInformation['termsig'] = -1;
|
$this->processInformation['termsig'] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,7 +1405,7 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets data related to the latest run of the Process.
|
* Resets data related to the latest run of the process.
|
||||||
*/
|
*/
|
||||||
private function resetProcessData()
|
private function resetProcessData()
|
||||||
{
|
{
|
||||||
|
@ -1417,10 +1413,10 @@ class Process implements \IteratorAggregate
|
||||||
$this->callback = null;
|
$this->callback = null;
|
||||||
$this->exitcode = null;
|
$this->exitcode = null;
|
||||||
$this->fallbackStatus = [];
|
$this->fallbackStatus = [];
|
||||||
$this->ProcessInformation = null;
|
$this->processInformation = null;
|
||||||
$this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
|
$this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
|
||||||
$this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
|
$this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
|
||||||
$this->Process = null;
|
$this->process = null;
|
||||||
$this->latestSignal = null;
|
$this->latestSignal = null;
|
||||||
$this->status = self::STATUS_READY;
|
$this->status = self::STATUS_READY;
|
||||||
$this->incrementalOutputOffset = 0;
|
$this->incrementalOutputOffset = 0;
|
||||||
|
@ -1428,20 +1424,20 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a POSIX signal to the Process.
|
* Sends a POSIX signal to the process.
|
||||||
*
|
*
|
||||||
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
|
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
|
||||||
* @param bool $throwException Whether to throw exception in case signal failed
|
* @param bool $throwException Whether to throw exception in case signal failed
|
||||||
*
|
*
|
||||||
* @throws LogicException In case the Process is not running
|
* @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 --enable-sigchild is activated and the process can't be killed
|
||||||
* @throws RuntimeException In case of failure
|
* @throws RuntimeException In case of failure
|
||||||
*/
|
*/
|
||||||
private function doSignal(int $signal, bool $throwException): bool
|
private function doSignal(int $signal, bool $throwException): bool
|
||||||
{
|
{
|
||||||
if (null === $pid = $this->getPid()) {
|
if (null === $pid = $this->getPid()) {
|
||||||
if ($throwException) {
|
if ($throwException) {
|
||||||
throw new LogicException('Cannot send signal on a non running Process.');
|
throw new LogicException('Cannot send signal on a non running process.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1451,14 +1447,14 @@ class Process implements \IteratorAggregate
|
||||||
exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
|
exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
|
||||||
if ($exitCode && $this->isRunning()) {
|
if ($exitCode && $this->isRunning()) {
|
||||||
if ($throwException) {
|
if ($throwException) {
|
||||||
throw new RuntimeException(sprintf('Unable to kill the Process (%s).', implode(' ', $output)));
|
throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!$this->isSigchildEnabled()) {
|
if (!$this->isSigchildEnabled()) {
|
||||||
$ok = @proc_terminate($this->Process, $signal);
|
$ok = @proc_terminate($this->process, $signal);
|
||||||
} elseif (\function_exists('posix_kill')) {
|
} elseif (\function_exists('posix_kill')) {
|
||||||
$ok = @posix_kill($pid, $signal);
|
$ok = @posix_kill($pid, $signal);
|
||||||
} elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), [2 => ['pipe', 'w']], $pipes)) {
|
} elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), [2 => ['pipe', 'w']], $pipes)) {
|
||||||
|
@ -1520,7 +1516,7 @@ class Process implements \IteratorAggregate
|
||||||
);
|
);
|
||||||
|
|
||||||
$cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
|
$cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
|
||||||
foreach ($this->ProcessPipes->getFiles() as $offset => $filename) {
|
foreach ($this->processPipes->getFiles() as $offset => $filename) {
|
||||||
$cmd .= ' '.$offset.'>"'.$filename.'"';
|
$cmd .= ' '.$offset.'>"'.$filename.'"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1528,9 +1524,9 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the Process is running or terminated, throws a LogicException if the Process has a not started.
|
* Ensures the process is running or terminated, throws a LogicException if the process has a not started.
|
||||||
*
|
*
|
||||||
* @throws LogicException if the Process has not run
|
* @throws LogicException if the process has not run
|
||||||
*/
|
*/
|
||||||
private function requireProcessIsStarted(string $functionName)
|
private function requireProcessIsStarted(string $functionName)
|
||||||
{
|
{
|
||||||
|
@ -1540,9 +1536,9 @@ class Process implements \IteratorAggregate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the Process is terminated, throws a LogicException if the Process has a status different than "terminated".
|
* Ensures the process is terminated, throws a LogicException if the process has a status different than "terminated".
|
||||||
*
|
*
|
||||||
* @throws LogicException if the Process is not yet terminated
|
* @throws LogicException if the process is not yet terminated
|
||||||
*/
|
*/
|
||||||
private function requireProcessIsTerminated(string $functionName)
|
private function requireProcessIsTerminated(string $functionName)
|
||||||
{
|
{
|
||||||
|
|
4
src/ncc/ThirdParty/Symfony/Process/README.md
vendored
4
src/ncc/ThirdParty/Symfony/Process/README.md
vendored
|
@ -1,7 +1,7 @@
|
||||||
Process Component
|
Process Component
|
||||||
=================
|
=================
|
||||||
|
|
||||||
The Process component executes commands in sub-Processes.
|
The Process component executes commands in sub-processes.
|
||||||
|
|
||||||
Sponsor
|
Sponsor
|
||||||
-------
|
-------
|
||||||
|
@ -17,7 +17,7 @@ Help Symfony by [sponsoring][3] its development!
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
* [Documentation](https://symfony.com/doc/current/components/Process.html)
|
* [Documentation](https://symfony.com/doc/current/components/process.html)
|
||||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||||
|
|
2
src/ncc/ThirdParty/Symfony/Process/VERSION
vendored
2
src/ncc/ThirdParty/Symfony/Process/VERSION
vendored
|
@ -1 +1 @@
|
||||||
6.1.3
|
6.2.5
|
Loading…
Add table
Reference in a new issue