diff options
Diffstat (limited to 'library/symfony/process/Pipes')
-rw-r--r-- | library/symfony/process/Pipes/AbstractPipes.php | 74 | ||||
-rw-r--r-- | library/symfony/process/Pipes/PipesInterface.php | 60 | ||||
-rw-r--r-- | library/symfony/process/Pipes/UnixPipes.php | 214 | ||||
-rw-r--r-- | library/symfony/process/Pipes/WindowsPipes.php | 253 |
4 files changed, 0 insertions, 601 deletions
diff --git a/library/symfony/process/Pipes/AbstractPipes.php b/library/symfony/process/Pipes/AbstractPipes.php deleted file mode 100644 index 1ca85739f..000000000 --- a/library/symfony/process/Pipes/AbstractPipes.php +++ /dev/null @@ -1,74 +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\Pipes; - -/** - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -abstract class AbstractPipes implements PipesInterface -{ - /** @var array */ - public $pipes = array(); - - /** @var string */ - protected $inputBuffer = ''; - /** @var resource|null */ - protected $input; - - /** @var bool */ - private $blocked = true; - - /** - * {@inheritdoc} - */ - public function close() - { - foreach ($this->pipes as $pipe) { - fclose($pipe); - } - $this->pipes = array(); - } - - /** - * Returns true if a system call has been interrupted. - * - * @return bool - */ - protected function hasSystemCallBeenInterrupted() - { - $lastError = error_get_last(); - - // stream_select returns false when the `select` system call is interrupted by an incoming signal - return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call'); - } - - /** - * Unblocks streams. - */ - protected function unblock() - { - if (!$this->blocked) { - return; - } - - foreach ($this->pipes as $pipe) { - stream_set_blocking($pipe, 0); - } - if (null !== $this->input) { - stream_set_blocking($this->input, 0); - } - - $this->blocked = false; - } -} diff --git a/library/symfony/process/Pipes/PipesInterface.php b/library/symfony/process/Pipes/PipesInterface.php deleted file mode 100644 index 09d3f61d6..000000000 --- a/library/symfony/process/Pipes/PipesInterface.php +++ /dev/null @@ -1,60 +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\Pipes; - -/** - * PipesInterface manages descriptors and pipes for the use of proc_open. - * - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -interface PipesInterface -{ - const CHUNK_SIZE = 16384; - - /** - * Returns an array of descriptors for the use of proc_open. - * - * @return array - */ - public function getDescriptors(); - - /** - * Returns an array of filenames indexed by their related stream in case these pipes use temporary files. - * - * @return string[] - */ - public function getFiles(); - - /** - * Reads data in file handles and pipes. - * - * @param bool $blocking Whether to use blocking calls or not. - * @param bool $close Whether to close pipes if they've reached EOF. - * - * @return string[] An array of read data indexed by their fd. - */ - public function readAndWrite($blocking, $close = false); - - /** - * Returns if the current state has open file handles or pipes. - * - * @return bool - */ - public function areOpen(); - - /** - * Closes file handles and pipes. - */ - public function close(); -} diff --git a/library/symfony/process/Pipes/UnixPipes.php b/library/symfony/process/Pipes/UnixPipes.php deleted file mode 100644 index f8a0d1997..000000000 --- a/library/symfony/process/Pipes/UnixPipes.php +++ /dev/null @@ -1,214 +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\Pipes; - -use Symfony\Component\Process\Process; - -/** - * UnixPipes implementation uses unix pipes as handles. - * - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -class UnixPipes extends AbstractPipes -{ - /** @var bool */ - private $ttyMode; - /** @var bool */ - private $ptyMode; - /** @var bool */ - private $disableOutput; - - public function __construct($ttyMode, $ptyMode, $input, $disableOutput) - { - $this->ttyMode = (bool) $ttyMode; - $this->ptyMode = (bool) $ptyMode; - $this->disableOutput = (bool) $disableOutput; - - if (is_resource($input)) { - $this->input = $input; - } else { - $this->inputBuffer = (string) $input; - } - } - - public function __destruct() - { - $this->close(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors() - { - if ($this->disableOutput) { - $nullstream = fopen('/dev/null', 'c'); - - return array( - array('pipe', 'r'), - $nullstream, - $nullstream, - ); - } - - if ($this->ttyMode) { - return array( - array('file', '/dev/tty', 'r'), - array('file', '/dev/tty', 'w'), - array('file', '/dev/tty', 'w'), - ); - } - - if ($this->ptyMode && Process::isPtySupported()) { - return array( - array('pty'), - array('pty'), - array('pty'), - ); - } - - return array( - array('pipe', 'r'), - array('pipe', 'w'), // stdout - array('pipe', 'w'), // stderr - ); - } - - /** - * {@inheritdoc} - */ - public function getFiles() - { - return array(); - } - - /** - * {@inheritdoc} - */ - public function readAndWrite($blocking, $close = false) - { - // only stdin is left open, job has been done ! - // we can now close it - if (1 === count($this->pipes) && array(0) === array_keys($this->pipes)) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - - if (empty($this->pipes)) { - return array(); - } - - $this->unblock(); - - $read = array(); - - if (null !== $this->input) { - // if input is a resource, let's add it to stream_select argument to - // fill a buffer - $r = array_merge($this->pipes, array('input' => $this->input)); - } else { - $r = $this->pipes; - } - // discard read on stdin - unset($r[0]); - - $w = isset($this->pipes[0]) ? array($this->pipes[0]) : null; - $e = null; - - // let's have a look if something changed in streams - if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - // if a system call has been interrupted, forget about it, let's try again - // otherwise, an error occurred, let's reset pipes - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = array(); - } - - return $read; - } - - // nothing has changed - if (0 === $n) { - return $read; - } - - foreach ($r as $pipe) { - // prior PHP 5.4 the array passed to stream_select is modified and - // lose key association, we have to find back the key - $type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : 'input'; - $data = ''; - while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) { - $data .= $dataread; - } - - if ('' !== $data) { - if ($type === 'input') { - $this->inputBuffer .= $data; - } else { - $read[$type] = $data; - } - } - - if (false === $data || (true === $close && feof($pipe) && '' === $data)) { - if ($type === 'input') { - // no more data to read on input resource - // use an empty buffer in the next reads - $this->input = null; - } else { - fclose($this->pipes[$type]); - unset($this->pipes[$type]); - } - } - } - - if (null !== $w && 0 < count($w)) { - while (strlen($this->inputBuffer)) { - $written = fwrite($w[0], $this->inputBuffer, 2 << 18); // write 512k - if ($written > 0) { - $this->inputBuffer = (string) substr($this->inputBuffer, $written); - } else { - break; - } - } - } - - // no input to read on resource, buffer is empty and stdin still open - if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function areOpen() - { - return (bool) $this->pipes; - } - - /** - * Creates a new UnixPipes instance. - * - * @param Process $process - * @param string|resource $input - * - * @return UnixPipes - */ - public static function create(Process $process, $input) - { - return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled()); - } -} diff --git a/library/symfony/process/Pipes/WindowsPipes.php b/library/symfony/process/Pipes/WindowsPipes.php deleted file mode 100644 index 1472f8c6c..000000000 --- a/library/symfony/process/Pipes/WindowsPipes.php +++ /dev/null @@ -1,253 +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\Pipes; - -use Symfony\Component\Process\Process; -use Symfony\Component\Process\Exception\RuntimeException; - -/** - * 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 - * - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -class WindowsPipes extends AbstractPipes -{ - /** @var array */ - private $files = array(); - /** @var array */ - private $fileHandles = array(); - /** @var array */ - private $readBytes = array( - Process::STDOUT => 0, - Process::STDERR => 0, - ); - /** @var bool */ - private $disableOutput; - - public function __construct($disableOutput, $input) - { - $this->disableOutput = (bool) $disableOutput; - - if (!$this->disableOutput) { - // 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 - $this->files = array( - Process::STDOUT => tempnam(sys_get_temp_dir(), 'out_sf_proc'), - Process::STDERR => tempnam(sys_get_temp_dir(), 'err_sf_proc'), - ); - foreach ($this->files as $offset => $file) { - if (false === $file || false === $this->fileHandles[$offset] = fopen($file, 'rb')) { - throw new RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable'); - } - } - } - - if (is_resource($input)) { - $this->input = $input; - } else { - $this->inputBuffer = $input; - } - } - - public function __destruct() - { - $this->close(); - $this->removeFiles(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors() - { - if ($this->disableOutput) { - $nullstream = fopen('NUL', 'c'); - - return array( - array('pipe', 'r'), - $nullstream, - $nullstream, - ); - } - - // 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 - // So we redirect output within the commandline and pass the nul device to the process - return array( - array('pipe', 'r'), - array('file', 'NUL', 'w'), - array('file', 'NUL', 'w'), - ); - } - - /** - * {@inheritdoc} - */ - public function getFiles() - { - return $this->files; - } - - /** - * {@inheritdoc} - */ - public function readAndWrite($blocking, $close = false) - { - $this->write($blocking, $close); - - $read = array(); - $fh = $this->fileHandles; - foreach ($fh as $type => $fileHandle) { - if (0 !== fseek($fileHandle, $this->readBytes[$type])) { - continue; - } - $data = ''; - $dataread = null; - while (!feof($fileHandle)) { - if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) { - $data .= $dataread; - } - } - if (0 < $length = strlen($data)) { - $this->readBytes[$type] += $length; - $read[$type] = $data; - } - - if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) { - fclose($this->fileHandles[$type]); - unset($this->fileHandles[$type]); - } - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function areOpen() - { - return (bool) $this->pipes && (bool) $this->fileHandles; - } - - /** - * {@inheritdoc} - */ - public function close() - { - parent::close(); - foreach ($this->fileHandles as $handle) { - fclose($handle); - } - $this->fileHandles = array(); - } - - /** - * Creates a new WindowsPipes instance. - * - * @param Process $process The process - * @param $input - * - * @return WindowsPipes - */ - public static function create(Process $process, $input) - { - return new static($process->isOutputDisabled(), $input); - } - - /** - * Removes temporary files. - */ - private function removeFiles() - { - foreach ($this->files as $filename) { - if (file_exists($filename)) { - @unlink($filename); - } - } - $this->files = array(); - } - - /** - * Writes input to stdin. - * - * @param bool $blocking - * @param bool $close - */ - private function write($blocking, $close) - { - if (empty($this->pipes)) { - return; - } - - $this->unblock(); - - $r = null !== $this->input ? array('input' => $this->input) : null; - $w = isset($this->pipes[0]) ? array($this->pipes[0]) : null; - $e = null; - - // let's have a look if something changed in streams - if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - // if a system call has been interrupted, forget about it, let's try again - // otherwise, an error occurred, let's reset pipes - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = array(); - } - - return; - } - - // nothing has changed - if (0 === $n) { - return; - } - - if (null !== $w && 0 < count($r)) { - $data = ''; - while ($dataread = fread($r['input'], self::CHUNK_SIZE)) { - $data .= $dataread; - } - - $this->inputBuffer .= $data; - - if (false === $data || (true === $close && feof($r['input']) && '' === $data)) { - // no more data to read on input resource - // use an empty buffer in the next reads - $this->input = null; - } - } - - if (null !== $w && 0 < count($w)) { - while (strlen($this->inputBuffer)) { - $written = fwrite($w[0], $this->inputBuffer, 2 << 18); - if ($written > 0) { - $this->inputBuffer = (string) substr($this->inputBuffer, $written); - } else { - break; - } - } - } - - // no input to read on resource, buffer is empty and stdin still open - if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - } -} |