8000 [Process] Fix pipes handling · symfony/symfony@c86131b · GitHub
[go: up one dir, main page]

Skip to content

Commit c86131b

Browse files
[Process] Fix pipes handling
1 parent a1c95f7 commit c86131b

File tree

2 files changed

+39
-54
lines changed

2 files changed

+39
-54
lines changed

src/Symfony/Component/Process/Pipes/UnixPipes.php

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,10 @@ public function readAndWrite($blocking, $close = false)
114114
$this->unblock();
115115

116116
$read = array();
117+
$r = $this->pipes;
117118

118119
if (null !== $this->input) {
119-
// if input is a resource, let's add it to stream_select argument to
120-
// fill a buffer
121-
$r = array_merge($this->pipes, array('input' => $this->input));
122-
} else {
123-
$r = $this->pipes;
120+
$r['input'] = $this->input;
124121
}
125122
// discard read on stdin
126123
unset($r[0]);
@@ -147,22 +144,17 @@ public function readAndWrite($blocking, $close = false)
147144
foreach ($r as $pipe) {
148145
// prior PHP 5.4 the array passed to stream_select is modified and
149146
// lose key association, we have to find back the key
150-
$type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : 'input';
151-
$data = '';
152-
if ($type !== 'input') {
153-
while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) {
154-
$data .= $dataread;
155-
}
156-
// Remove extra null chars returned by fread
157-
if ('' !== $data) {
158-
$read[$type] = rtrim($data, "\x00");
147+
$type = (false !== $type = array_search($pipe, $this->pipes, true)) ? $type : 'input';
148+
$data = fread($pipe, self::CHUNK_SIZE);
149+
150+
if (isset($data[0])) {
151+
if ('input' !== $type) {
152+
$read[$type] = $data;
153+
} elseif (isset($this->pipes[0])) {
154+
$this->inputBuffer .= $data;
159155
}
160-
} elseif (isset($w[0])) {
161-
stream_copy_to_stream($this->input, $w[0], 4096);
162-
}
163-
164-
if (false === $data || (true === $close && feof($pipe) && '' === $data)) {
165-
if ($type === 'input') {
156+
} elseif (!isset($data[0]) && $close && feof($pipe)) {
157+
if ('input' === $type) {
166158
// no more data to read on input resource
167159
// use an empty buffer in the next reads
168160
$this->input = null;
@@ -173,8 +165,15 @@ public function readAndWrite($blocking, $close = false)
173165
}
174166
}
175167

176-
// no input to read on resource and stdin still open
177-
if (null === $this->input && isset($this->pipes[0])) {
168+
if (isset($this->inputBuffer[0])) {
169+
foreach ($w as $pipe) {
170+
$written = fwrite($pipe, $this->inputBuffer);
171+
$this->inputBuffer = substr($this->inputBuffer, $written);
172+
}
173+
}
174+
175+
// no input to read on resource, buffer is empty and stdin still open
176+
if (!isset($this->inputBuffer[0]) && null === $this->input && isset($this->pipes[0])) {
178177
fclose($this->pipes[0]);
179178
unset($this->pipes[0]);
180179
}

src/Symfony/Component/Process/Pipes/WindowsPipes.php

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,18 @@ public function __construct($disableOutput, $input)
5252
Process::STDERR => tempnam(sys_get_temp_dir(), 'err_sf_proc'),
5353
);
5454
foreach ($this->files as $offset => $file) {
55-
if (false === $file || false === $this->fileHandles[$offset] = fopen($file, 'rb')) {
55+
if (false === $file || false === $this->fileHandles[$offset] = @fopen($file, 'rb')) {
5656
throw new RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable');
5757
}
5858
}
5959
}
6060

6161
if (is_resource($input)) {
6262
$this->input = $input;
63-
} else {
63+
} elseif (is_string($input)) {
6464
$this->inputBuffer = $input;
65+
} else {
66+
$this->inputBuffer = (string) $input;
6567
}
6668
}
6769

@@ -117,19 +119,12 @@ public function readAndWrite($blocking, $close = false)
117119
if (0 !== fseek($fileHandle, $this->readBytes[$type])) {
118120
continue;
119121
}
120-
$data = '';
121-
$dataread = null;
122-
while (!feof($fileHandle)) {
123-
if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) {
124-
$data .= $dataread;
125-
}
126-
}
127-
if (0 < $length = strlen($data)) {
128-
$this->readBytes[$type] += $length;
129-
$read[$type] = $data;
130-
}
122+
$data = fread($fileHandle, self::CHUNK_SIZE);
131123

132-
if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) {
124+
if (isset($data[0])) {
125+
$this->readBytes[$type] += strlen($data);
126+
$read[$type] = $data;
127+
} elseif ($close && feof($fileHandle)) {
133128
fclose($this->fileHandles[$type]);
134129
unset($this->fileHandles[$type]);
135130
}
@@ -143,7 +138,7 @@ public function readAndWrite($blocking, $close = false)
143138
*/
144139
public function areOpen()
145140
{
146-
return (bool) $this->pipes && (bool) $this->fileHandles;
141+
return $this->pipes && $this->fileHandles;
147142
}
148143

149144
/**
@@ -218,34 +213,25 @@ private function write($blocking, $close)
218213
return;
219214
}
220215

221-
if (null !== $w && 0 < count($r)) {
222-
$data = '';
223-
while ($dataread = fread($r['input'], self::CHUNK_SIZE)) {
224-
$data .= $dataread;
225-
}
216+
foreach ($r as $pipe) {
217+
$this->inputBuffer .= $data = fread($pipe, self::CHUNK_SIZE);
226218

227-
$this->inputBuffer .= $data;
228-
229-
if (false === $data || (true === $close && feof($r['input']) && '' === $data)) {
219+
if (!isset($data[0]) && $close && feof($pipe)) {
230220
// no more data to read on input resource
231221
// use an empty buffer in the next reads
232222
$this->input = null;
233223
}
234224
}
235225

236-
if (null !== $w && 0 < count($w)) {
237-
while (strlen($this->inputBuffer)) {
238-
$written = fwrite($w[0], $this->inputBuffer, 2 << 18);
239-
if ($written > 0) {
240-
$this->inputBuffer = (string) substr($this->inputBuffer, $written);
241-
} else {
242-
break;
243-
}
226+
if (isset($this->inputBuffer[0])) {
227+
foreach ($w as $pipe) {
228+
$written = fwrite($pipe, $this->inputBuffer);
229+
$this->inputBuffer = substr($this->inputBuffer, $written);
244230
}
245231
}
246232

247233
// no input to read on resource, buffer is empty and stdin still open
248-
if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) {
234+
if (!isset($this->inputBuffer[0]) && null === $this->input && isset($this->pipes[0])) {
249235
fclose($this->pipes[0]);
250236
unset($this->pipes[0]);
251237
}

0 commit comments

Comments
 (0)
0