From 7793c364fc59a480c94387f8f42681d9e28f2658 Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 30 Nov 2015 02:41:51 -0800 Subject: [PATCH] child_process: flush consuming streams When a client calls read() with a nonzero argument on a Socket, that Socket sets this._consuming to true. It never sets this._consuming back to false. ChildProcess.flushStdio() currently doesn't flush any streams where _consuming is truthy. But, that means that it never flushes any stream that has ever been read from. This prevents a child process from ever closing if one of its streams has been read from, causing issue #4049. This commit allows consuming streams to be flushed, and the child process to emit a close event. Fixes: https://github.com/nodejs/node/issues/4049 PR-URL: https://github.com/nodejs/node/pull/4071 Reviewed-By: Colin Ihrig --- lib/internal/child_process.js | 2 +- test/parallel/test-child-process-flush-stdio.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-child-process-flush-stdio.js diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index e93e1ae2e62c79..04bd270b185974 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -217,7 +217,7 @@ 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) + if (!stream || !stream.readable) return; stream.resume(); }); diff --git a/test/parallel/test-child-process-flush-stdio.js b/test/parallel/test-child-process-flush-stdio.js new file mode 100644 index 00000000000000..5fd7eb3bc99922 --- /dev/null +++ b/test/parallel/test-child-process-flush-stdio.js @@ -0,0 +1,17 @@ +'use strict'; +const cp = require('child_process'); +const common = require('../common'); +const assert = require('assert'); + +const p = cp.spawn('echo'); + +p.on('close', common.mustCall(function(code, signal) { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); +})); + +p.stdout.read(); + +setTimeout(function() { + p.kill(); +}, 100);