ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
AbstractPipes.php
Go to the documentation of this file.
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 
13 
15 
21 abstract class AbstractPipes implements PipesInterface
22 {
24  public $pipes = array();
25 
27  private $inputBuffer = '';
29  private $input;
31  private $blocked = true;
32 
33  public function __construct($input)
34  {
35  if (is_resource($input) || $input instanceof \Iterator) {
36  $this->input = $input;
37  } elseif (is_string($input)) {
38  $this->inputBuffer = $input;
39  } else {
40  $this->inputBuffer = (string) $input;
41  }
42  }
43 
47  public function close()
48  {
49  foreach ($this->pipes as $pipe) {
50  fclose($pipe);
51  }
52  $this->pipes = array();
53  }
54 
60  protected function hasSystemCallBeenInterrupted()
61  {
62  $lastError = error_get_last();
63 
64  // stream_select returns false when the `select` system call is interrupted by an incoming signal
65  return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call');
66  }
67 
71  protected function unblock()
72  {
73  if (!$this->blocked) {
74  return;
75  }
76 
77  foreach ($this->pipes as $pipe) {
78  stream_set_blocking($pipe, 0);
79  }
80  if (is_resource($this->input)) {
81  stream_set_blocking($this->input, 0);
82  }
83 
84  $this->blocked = false;
85  }
86 
92  protected function write()
93  {
94  if (!isset($this->pipes[0])) {
95  return;
96  }
98 
99  if ($input instanceof \Iterator) {
100  if (!$input->valid()) {
101  $input = null;
102  } elseif (is_resource($input = $input->current())) {
103  stream_set_blocking($input, 0);
104  } elseif (!isset($this->inputBuffer[0])) {
105  if (!is_string($input)) {
106  if (!is_scalar($input)) {
107  throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported', get_class($this->input), gettype($input)));
108  }
109  $input = (string) $input;
110  }
111  $this->inputBuffer = $input;
112  $this->input->next();
113  $input = null;
114  } else {
115  $input = null;
116  }
117  }
118 
119  $r = $e = array();
120  $w = array($this->pipes[0]);
121 
122  // let's have a look if something changed in streams
123  if (false === $n = @stream_select($r, $w, $e, 0, 0)) {
124  return;
125  }
126 
127  foreach ($w as $stdin) {
128  if (isset($this->inputBuffer[0])) {
129  $written = fwrite($stdin, $this->inputBuffer);
130  $this->inputBuffer = substr($this->inputBuffer, $written);
131  if (isset($this->inputBuffer[0])) {
132  return array($this->pipes[0]);
133  }
134  }
135 
136  if ($input) {
137  for (;;) {
138  $data = fread($input, self::CHUNK_SIZE);
139  if (!isset($data[0])) {
140  break;
141  }
142  $written = fwrite($stdin, $data);
143  $data = substr($data, $written);
144  if (isset($data[0])) {
145  $this->inputBuffer = $data;
146 
147  return array($this->pipes[0]);
148  }
149  }
150  if (feof($input)) {
151  if ($this->input instanceof \Iterator) {
152  $this->input->next();
153  } else {
154  $this->input = null;
155  }
156  }
157  }
158  }
159 
160  // no input to read on resource, buffer is empty
161  if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) {
162  $this->input = null;
163  fclose($this->pipes[0]);
164  unset($this->pipes[0]);
165  }
166 
167  if (!$w) {
168  return array($this->pipes[0]);
169  }
170  }
171 }
Add rich text string
The name of the decorator.
$w
$r
Definition: example_031.php:79
input
Definition: langcheck.php:166
hasSystemCallBeenInterrupted()
Returns true if a system call has been interrupted.
$n
Definition: RandomTest.php:80
Create styles array
The data for the language used.
PipesInterface manages descriptors and pipes for the use of proc_open.
close()
{Closes file handles and pipes.}