child_process: execFileSync stderr should inherit
authorTimothy J Fontaine <tjfontaine@gmail.com>
Tue, 18 Feb 2014 00:29:23 +0000 (16:29 -0800)
committerFedor Indutny <fedor.indutny@gmail.com>
Tue, 18 Feb 2014 12:03:13 +0000 (16:03 +0400)
If you don't set your options.stdio for execSync and execFileSync
capture and write to stderr of the parent process by default.

Fixes #7110

doc/api/child_process.markdown
lib/child_process.js
test/common.js
test/simple/test-child-process-spawnsync-input.js

index 8c1d0f0..e1d6c1f 100644 (file)
@@ -628,7 +628,9 @@ process has exited.
   * `cwd` {String} Current working directory of the child process
   * `input` {String|Buffer} The value which will be passed as stdin to the spawned process
     - supplying this value will override `stdio[0]`
-  * `stdio` {Array} Child's stdio configuration.
+  * `stdio` {Array} Child's stdio configuration. (Default: 'pipe')
+    - `stderr` by default will be output to the parent process' stderr unless
+      `stdio` is specified
   * `env` {Object} Environment key-value pairs
   * `uid` {Number} Sets the user identity of the process. (See setuid(2).)
   * `gid` {Number} Sets the group identity of the process. (See setgid(2).)
@@ -656,7 +658,9 @@ throw.  The `Error` object will contain the entire result from
   * `cwd` {String} Current working directory of the child process
   * `input` {String|Buffer} The value which will be passed as stdin to the spawned process
     - supplying this value will override `stdio[0]`
-  * `stdio` {Array} Child's stdio configuration.
+  * `stdio` {Array} Child's stdio configuration. (Default: 'pipe')
+    - `stderr` by default will be output to the parent process' stderr unless
+      `stdio` is specified
   * `env` {Object} Environment key-value pairs
   * `uid` {Number} Sets the user identity of the process. (See setuid(2).)
   * `gid` {Number} Sets the group identity of the process. (See setgid(2).)
index 1f121d9..f606224 100644 (file)
@@ -1304,7 +1304,13 @@ function checkExecSyncError(ret) {
 
 
 function execFileSync(/*command, options*/) {
-  var ret = spawnSync.apply(null, arguments);
+  var opts = normalizeSpawnArguments.apply(null, arguments);
+  var inheritStderr = !!!opts.options.stdio;
+
+  var ret = spawnSync(opts.file, opts.args.slice(1), opts.options);
+
+  if (inheritStderr)
+    process.stderr.write(ret.stderr);
 
   var err = checkExecSyncError(ret);
 
@@ -1318,9 +1324,14 @@ exports.execFileSync = execFileSync;
 
 function execSync(/*comand, options*/) {
   var opts = normalizeExecArgs.apply(null, arguments);
+  var inheritStderr = opts.options ? !!!opts.options.stdio : true;
+
   var ret = spawnSync(opts.file, opts.args, opts.options);
   ret.cmd = opts.cmd;
 
+  if (inheritStderr)
+    process.stderr.write(ret.stderr);
+
   var err = checkExecSyncError(ret);
 
   if (err)
index d44f0ea..40f7072 100644 (file)
@@ -214,3 +214,8 @@ exports.mustCall = function(fn, expected) {
     return fn.apply(this, arguments);
   };
 };
+
+exports.checkSpawnSyncRet = function(ret) {
+  assert.strictEqual(ret.status, 0);
+  assert.strictEqual(ret.error, undefined);
+};
index 2bcf043..66b2fa3 100644 (file)
@@ -26,11 +26,6 @@ var util = require('util');
 
 var spawnSync = require('child_process').spawnSync;
 
-function checkRet(ret) {
-  assert.strictEqual(ret.status, 0);
-  assert.strictEqual(ret.error, undefined);
-}
-
 var msgOut = 'this is stdout';
 var msgErr = 'this is stderr';
 
@@ -50,13 +45,13 @@ if (process.argv.indexOf('spawnchild') !== -1) {
   switch (process.argv[3]) {
     case '1':
       ret = spawnSync(process.execPath, args, { stdio: 'inherit' });
-      checkRet(ret);
+      common.checkSpawnSyncRet(ret);
       break;
     case '2':
       ret = spawnSync(process.execPath, args, {
         stdio: ['inherit', 'inherit', 'inherit']
       });
-      checkRet(ret);
+      common.checkSpawnSyncRet(ret);
       break;
   }
   process.exit(0);
@@ -65,7 +60,7 @@ if (process.argv.indexOf('spawnchild') !== -1) {
 
 
 function verifyBufOutput(ret) {
-  checkRet(ret);
+  common.checkSpawnSyncRet(ret);
   assert.deepEqual(ret.stdout, msgOutBuf);
   assert.deepEqual(ret.stderr, msgErrBuf);
 }
@@ -89,7 +84,7 @@ options = {
 
 ret = spawnSync('cat', [], options);
 
-checkRet(ret);
+common.checkSpawnSyncRet(ret);
 assert.strictEqual(ret.stdout.toString('utf8'), options.input);
 assert.strictEqual(ret.stderr.toString('utf8'), '');
 
@@ -99,7 +94,7 @@ options = {
 
 ret = spawnSync('cat', [], options);
 
-checkRet(ret);
+common.checkSpawnSyncRet(ret);
 assert.deepEqual(ret.stdout, options.input);
 assert.deepEqual(ret.stderr, new Buffer(''));
 
@@ -107,7 +102,7 @@ verifyBufOutput(spawnSync(process.execPath, args));
 
 ret = spawnSync(process.execPath, args, { encoding: 'utf8' });
 
-checkRet(ret);
+common.checkSpawnSyncRet(ret);
 assert.strictEqual(ret.stdout, msgOut + '\n');
 assert.strictEqual(ret.stderr, msgErr + '\n');