Просмотр файла vendor/symfony/process/Pipes/UnixPipes.php

Размер файла: 3.57Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace Symfony\Component\Process\Pipes;
  13.  
  14. use Symfony\Component\Process\Process;
  15.  
  16. /**
  17. * UnixPipes implementation uses unix pipes as handles.
  18. *
  19. * @author Romain Neutron <imprec@gmail.com>
  20. *
  21. * @internal
  22. */
  23. class UnixPipes extends AbstractPipes
  24. {
  25. /** @var bool */
  26. private $ttyMode;
  27. /** @var bool */
  28. private $ptyMode;
  29. /** @var bool */
  30. private $haveReadSupport;
  31.  
  32. public function __construct($ttyMode, $ptyMode, $input, $haveReadSupport)
  33. {
  34. $this->ttyMode = (bool) $ttyMode;
  35. $this->ptyMode = (bool) $ptyMode;
  36. $this->haveReadSupport = (bool) $haveReadSupport;
  37.  
  38. parent::__construct($input);
  39. }
  40.  
  41. public function __destruct()
  42. {
  43. $this->close();
  44. }
  45.  
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function getDescriptors()
  50. {
  51. if (!$this->haveReadSupport) {
  52. $nullstream = fopen('/dev/null', 'c');
  53.  
  54. return array(
  55. array('pipe', 'r'),
  56. $nullstream,
  57. $nullstream,
  58. );
  59. }
  60.  
  61. if ($this->ttyMode) {
  62. return array(
  63. array('file', '/dev/tty', 'r'),
  64. array('file', '/dev/tty', 'w'),
  65. array('file', '/dev/tty', 'w'),
  66. );
  67. }
  68.  
  69. if ($this->ptyMode && Process::isPtySupported()) {
  70. return array(
  71. array('pty'),
  72. array('pty'),
  73. array('pty'),
  74. );
  75. }
  76.  
  77. return array(
  78. array('pipe', 'r'),
  79. array('pipe', 'w'), // stdout
  80. array('pipe', 'w'), // stderr
  81. );
  82. }
  83.  
  84. /**
  85. * {@inheritdoc}
  86. */
  87. public function getFiles()
  88. {
  89. return array();
  90. }
  91.  
  92. /**
  93. * {@inheritdoc}
  94. */
  95. public function readAndWrite($blocking, $close = false)
  96. {
  97. $this->unblock();
  98. $w = $this->write();
  99.  
  100. $read = $e = array();
  101. $r = $this->pipes;
  102. unset($r[0]);
  103.  
  104. // let's have a look if something changed in streams
  105. if (($r || $w) && false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
  106. // if a system call has been interrupted, forget about it, let's try again
  107. // otherwise, an error occurred, let's reset pipes
  108. if (!$this->hasSystemCallBeenInterrupted()) {
  109. $this->pipes = array();
  110. }
  111.  
  112. return $read;
  113. }
  114.  
  115. foreach ($r as $pipe) {
  116. // prior PHP 5.4 the array passed to stream_select is modified and
  117. // lose key association, we have to find back the key
  118. $read[$type = array_search($pipe, $this->pipes, true)] = '';
  119.  
  120. do {
  121. $data = fread($pipe, self::CHUNK_SIZE);
  122. $read[$type] .= $data;
  123. } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));
  124.  
  125. if (!isset($read[$type][0])) {
  126. unset($read[$type]);
  127. }
  128.  
  129. if ($close && feof($pipe)) {
  130. fclose($pipe);
  131. unset($this->pipes[$type]);
  132. }
  133. }
  134.  
  135. return $read;
  136. }
  137.  
  138. /**
  139. * {@inheritdoc}
  140. */
  141. public function haveReadSupport()
  142. {
  143. return $this->haveReadSupport;
  144. }
  145.  
  146. /**
  147. * {@inheritdoc}
  148. */
  149. public function areOpen()
  150. {
  151. return (bool) $this->pipes;
  152. }
  153. }