From 6c468df9af5bfce9291e93402a2f35c42aa780ab Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 2 Feb 2016 01:50:34 -0500 Subject: [PATCH] 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: https://github.com/nodejs/node/issues/5034 PR-URL: https://github.com/nodejs/node/pull/5037 Reviewed-By: James M Snell --- lib/child_process.js | 7 +++++-- test/simple/test-child-process-flush-stdio.js | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 test/simple/test-child-process-flush-stdio.js diff --git a/lib/child_process.js b/lib/child_process.js index bc1a909fdc4562..9bb64e64b66cf3 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -1094,8 +1094,11 @@ util.inherits(ChildProcess, EventEmitter); function flushStdio(subprocess) { if (subprocess.stdio == null) return; subprocess.stdio.forEach(function(stream, fd, stdio) { - if (!stream || !stream.readable || stream._consuming || - stream._readableState.flowing) + if (!stream || + !stream.readable || + stream._consuming || + stream._readableState.flowing || + stream._readableState.readableListening) return; stream.resume(); }); diff --git a/test/simple/test-child-process-flush-stdio.js b/test/simple/test-child-process-flush-stdio.js new file mode 100644 index 00000000000000..b5140860813c2b --- /dev/null +++ b/test/simple/test-child-process-flush-stdio.js @@ -0,0 +1,17 @@ +'use strict'; +var cp = require('child_process'); +var common = require('../common'); +var assert = require('assert'); + +var buffer = []; +var p = cp.spawn('echo', ['123']); +p.on('close', common.mustCall(function(code, signal) { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(Buffer.concat(buffer).toString().trim(), '123'); +})); +p.stdout.on('readable', function() { + var buf; + while (buf = this.read()) + buffer.push(buf); +});