|
6 | 6 | const { |
7 | 7 | ArrayIsArray, |
8 | 8 | SymbolAsyncIterator, |
9 | | - SymbolIterator, |
10 | | - Promise |
| 9 | + SymbolIterator |
11 | 10 | } = primordials; |
12 | 11 |
|
13 | 12 | let eos; |
@@ -114,10 +113,6 @@ function isStream(obj) { |
114 | 113 | return isReadable(obj) || isWritable(obj); |
115 | 114 | } |
116 | 115 |
|
117 | | -function isStdio(obj) { |
118 | | - return obj === process.stdout || obj === process.stderr; |
119 | | -} |
120 | | - |
121 | 116 | function isIterable(obj, isAsync) { |
122 | 117 | if (!obj) return false; |
123 | 118 | if (isAsync === true) return typeof obj[SymbolAsyncIterator] === 'function'; |
@@ -151,32 +146,14 @@ async function pump(iterable, writable, finish) { |
151 | 146 | EE = require('events'); |
152 | 147 | } |
153 | 148 | let error; |
154 | | - writable.on('error', (err) => { |
155 | | - error = err; |
156 | | - }); |
157 | 149 | try { |
158 | | - let prev; |
159 | | - for await (const next of iterable) { |
160 | | - if (prev != null) { |
161 | | - if (!writable.write(prev)) { |
162 | | - if (writable.destroyed) return; |
163 | | - await EE.once(writable, 'drain'); |
164 | | - } |
| 150 | + for await (const chunk of iterable) { |
| 151 | + if (!writable.write(chunk)) { |
| 152 | + if (writable.destroyed) return; |
| 153 | + await EE.once(writable, 'drain'); |
165 | 154 | } |
166 | | - prev = next; |
167 | | - } |
168 | | - |
169 | | - if (prev != null) { |
170 | | - await new Promise((resolve, reject) => { |
171 | | - writable.write(prev, (err) => { |
172 | | - err ? reject(err) : resolve(); |
173 | | - }); |
174 | | - }); |
175 | | - } |
176 | | - |
177 | | - if (!isStdio(writable)) { |
178 | | - writable.end(); |
179 | 155 | } |
| 156 | + writable.end(); |
180 | 157 | } catch (err) { |
181 | 158 | error = err; |
182 | 159 | } finally { |
@@ -225,7 +202,7 @@ function pipeline(...streams) { |
225 | 202 | const reading = i < streams.length - 1; |
226 | 203 | const writing = i > 0; |
227 | 204 |
|
228 | | - if (isStream(stream) && !isStdio(stream)) { |
| 205 | + if (isStream(stream)) { |
229 | 206 | finishCount++; |
230 | 207 | destroys.push(destroyer(stream, reading, writing, !reading, finish)); |
231 | 208 | } |
@@ -286,8 +263,15 @@ function pipeline(...streams) { |
286 | 263 | destroys.push(destroyer(ret, false, true, true, finish)); |
287 | 264 | } |
288 | 265 | } else if (isStream(stream)) { |
289 | | - if (isReadable(ret) && !isStdio(stream)) { |
| 266 | + if (isReadable(ret)) { |
290 | 267 | ret.pipe(stream); |
| 268 | + |
| 269 | + // Compat. Before node v10.12.0 stdio used to throw an error so |
| 270 | + // pipe() did/does not end() stdio destinations. |
| 271 | + // Now they allow it but "secretly" don't close the underlying fd. |
| 272 | + if (stream === process.stdout || stream === process.stderr) { |
| 273 | + ret.on('end', () => stream.end()); |
| 274 | + } |
291 | 275 | } else { |
292 | 276 | ret = makeAsyncIterable(ret); |
293 | 277 |
|
|
0 commit comments