Skip to content

Commit 12274a5

Browse files
committed
child_process: fix data loss with readable event
This commit prevents child process stdio streams from being automatically flushed on child process exit/close if a 'readable' event handler has been attached at the time of exit. Without this, child process stdio data can be lost if the process exits quickly and a `read()` (e.g. from a 'readable' handler) hasn't had the chance to get called yet. Fixes: #5034 PR-URL: #5036 Reviewed-By: Evan Lucas <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent ae244a2 commit 12274a5

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/internal/child_process.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ util.inherits(ChildProcess, EventEmitter);
217217
function flushStdio(subprocess) {
218218
if (subprocess.stdio == null) return;
219219
subprocess.stdio.forEach(function(stream, fd, stdio) {
220-
if (!stream || !stream.readable)
220+
if (!stream || !stream.readable || stream._readableState.readableListening)
221221
return;
222222
stream.resume();
223223
});

test/parallel/test-child-process-flush-stdio.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,22 @@ const p = cp.spawn('echo');
88
p.on('close', common.mustCall(function(code, signal) {
99
assert.strictEqual(code, 0);
1010
assert.strictEqual(signal, null);
11+
spawnWithReadable();
1112
}));
1213

1314
p.stdout.read();
1415

15-
setTimeout(function() {
16-
p.kill();
17-
}, 100);
16+
function spawnWithReadable() {
17+
const buffer = [];
18+
const p = cp.spawn('echo', ['123']);
19+
p.on('close', common.mustCall(function(code, signal) {
20+
assert.strictEqual(code, 0);
21+
assert.strictEqual(signal, null);
22+
assert.strictEqual(Buffer.concat(buffer).toString().trim(), '123');
23+
}));
24+
p.stdout.on('readable', function() {
25+
let buf;
26+
while (buf = this.read())
27+
buffer.push(buf);
28+
});
29+
}

0 commit comments

Comments
 (0)