@@ -5,6 +5,8 @@ var path = require('path');
55var fs = require ( 'fs' ) ;
66var child = require ( 'child_process' ) ;
77
8+ var DEFAULT_MAXBUFFER_SIZE = 20 * 1024 * 1024 ;
9+
810// Hack to run child_process.exec() synchronously (sync avoids callback hell)
911// Uses a custom wait loop that checks for a flag file, created when the child process is done.
1012// (Can't do a wait loop that checks for internal Node variables/messages as
@@ -18,15 +20,18 @@ function execSync(cmd, opts) {
1820 scriptFile = path . resolve ( tempDir + '/' + common . randomFileName ( ) ) ,
1921 sleepFile = path . resolve ( tempDir + '/' + common . randomFileName ( ) ) ;
2022
21- var options = common . extend ( {
22- silent : common . config . silent
23+ opts = common . extend ( {
24+ silent : common . config . silent ,
25+ cwd : _pwd ( ) ,
26+ env : process . env ,
27+ maxBuffer : DEFAULT_MAXBUFFER_SIZE
2328 } , opts ) ;
2429
2530 var previousStdoutContent = '' ,
2631 previousStderrContent = '' ;
2732 // Echoes stdout and stderr changes from running process, if not silent
2833 function updateStream ( streamFile ) {
29- if ( options . silent || ! fs . existsSync ( streamFile ) )
34+ if ( opts . silent || ! fs . existsSync ( streamFile ) )
3035 return ;
3136
3237 var previousStreamContent ,
@@ -58,19 +63,13 @@ function execSync(cmd, opts) {
5863 if ( fs . existsSync ( codeFile ) ) common . unlinkSync ( codeFile ) ;
5964
6065 var execCommand = '"' + process . execPath + '" ' + scriptFile ;
61- var execOptions = {
62- env : process . env ,
63- cwd : _pwd ( ) ,
64- maxBuffer : 20 * 1024 * 1024
65- } ;
66-
6766 var script ;
6867
6968 if ( typeof child . execSync === 'function' ) {
7069 script = [
7170 "var child = require('child_process')" ,
7271 " , fs = require('fs');" ,
73- "var childProcess = child.exec('" + escape ( cmd ) + "', {env: process.env, maxBuffer: 20*1024*1024 }, function(err) {" ,
72+ "var childProcess = child.exec('" + escape ( cmd ) + "', {env: process.env, maxBuffer: " + opts . maxBuffer + " }, function(err) {",
7473 " fs.writeFileSync('" + escape ( codeFile ) + "', err ? err.code.toString() : '0');" ,
7574 "});" ,
7675 "var stdoutStream = fs.createWriteStream('" + escape ( stdoutFile ) + "');" ,
@@ -88,28 +87,28 @@ function execSync(cmd, opts) {
8887
8988 fs . writeFileSync ( scriptFile , script ) ;
9089
91- if ( options . silent ) {
92- execOptions . stdio = 'ignore' ;
90+ if ( opts . silent ) {
91+ opts . stdio = 'ignore' ;
9392 } else {
94- execOptions . stdio = [ 0 , 1 , 2 ] ;
93+ opts . stdio = [ 0 , 1 , 2 ] ;
9594 }
9695
9796 // Welcome to the future
98- child . execSync ( execCommand , execOptions ) ;
97+ child . execSync ( execCommand , opts ) ;
9998 } else {
10099 cmd += ' > ' + stdoutFile + ' 2> ' + stderrFile ; // works on both win/unix
101100
102101 script = [
103102 "var child = require('child_process')" ,
104103 " , fs = require('fs');" ,
105- "var childProcess = child.exec('" + escape ( cmd ) + "', {env: process.env, maxBuffer: 20*1024*1024 }, function(err) {" ,
104+ "var childProcess = child.exec('" + escape ( cmd ) + "', {env: process.env, maxBuffer: " + opts . maxBuffer + " }, function(err) {",
106105 " fs.writeFileSync('" + escape ( codeFile ) + "', err ? err.code.toString() : '0');" ,
107106 "});"
108107 ] . join ( '\n' ) ;
109108
110109 fs . writeFileSync ( scriptFile , script ) ;
111110
112- child . exec ( execCommand , execOptions ) ;
111+ child . exec ( execCommand , opts ) ;
113112
114113 // The wait loop
115114 // sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage
@@ -156,24 +155,27 @@ function execAsync(cmd, opts, callback) {
156155 var stdout = '' ;
157156 var stderr = '' ;
158157
159- var options = common . extend ( {
160- silent : common . config . silent
158+ opts = common . extend ( {
159+ silent : common . config . silent ,
160+ cwd : _pwd ( ) ,
161+ env : process . env ,
162+ maxBuffer : DEFAULT_MAXBUFFER_SIZE
161163 } , opts ) ;
162164
163- var c = child . exec ( cmd , { env : process . env , maxBuffer : 20 * 1024 * 1024 } , function ( err ) {
165+ var c = child . exec ( cmd , opts , function ( err ) {
164166 if ( callback )
165167 callback ( err ? err . code : 0 , stdout , stderr ) ;
166168 } ) ;
167169
168170 c . stdout . on ( 'data' , function ( data ) {
169171 stdout += data ;
170- if ( ! options . silent )
172+ if ( ! opts . silent )
171173 process . stdout . write ( data ) ;
172174 } ) ;
173175
174176 c . stderr . on ( 'data' , function ( data ) {
175177 stderr += data ;
176- if ( ! options . silent )
178+ if ( ! opts . silent )
177179 process . stderr . write ( data ) ;
178180 } ) ;
179181
@@ -187,6 +189,8 @@ function execAsync(cmd, opts, callback) {
187189//@ + `async`: Asynchronous execution. If a callback is provided, it will be set to
188190//@ `true`, regardless of the passed value.
189191//@ + `silent`: Do not echo program output to console.
192+ //@ + and any option available to NodeJS's
193+ //@ [child_process.exec()](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)
190194//@
191195//@ Examples:
192196//@
@@ -233,9 +237,13 @@ function _exec(command, options, callback) {
233237 async : false
234238 } , options ) ;
235239
236- if ( options . async )
237- return execAsync ( command , options , callback ) ;
238- else
239- return execSync ( command , options ) ;
240+ try {
241+ if ( options . async )
242+ return execAsync ( command , options , callback ) ;
243+ else
244+ return execSync ( command , options ) ;
245+ } catch ( e ) {
246+ common . error ( 'internal error' ) ;
247+ }
240248}
241249module . exports = _exec ;
0 commit comments