@@ -21,12 +21,41 @@ function exec2(file, args /*, options, callback */) {
2121 }
2222
2323 var child = childproc . spawn ( file , args ) ;
24- var outputToStream = options . output != null ;
25- var stdout = outputToStream ? options . output : "" ;
26- var stderr = "" ;
2724 var killed = false ;
2825 var timedOut = false ;
2926
27+ var Wrapper = function ( output ) {
28+ this . stdout = output ;
29+ this . stderr = new Accumulator ( ) ;
30+ } ;
31+ Wrapper . prototype . out = function ( chunk , encoding ) { this . stdout . write ( chunk , encoding ) ; } ;
32+ Wrapper . prototype . err = function ( chunk , encoding ) { this . stderr . write ( chunk , encoding ) ; } ;
33+ Wrapper . prototype . finish = function ( err ) {
34+ this . stdout . end ( ) ;
35+ return [ err , this . stderr . current ( ) ] ;
36+ } ;
37+
38+ var Accumulator = function ( ) {
39+ this . stdout = { contents : "" } ;
40+ this . stderr = { contents : "" } ;
41+
42+ var limitedWrite = function ( stream ) {
43+ return function ( chunk ) {
44+ stream . contents += chunk ;
45+ if ( ! killed && stream . contents . length > options . maxBuffer ) {
46+ child . kill ( options . killSignal ) ;
47+ killed = true ;
48+ }
49+ } ;
50+ } ;
51+ this . out = limitedWrite ( this . stdout ) ;
52+ this . err = limitedWrite ( this . stderr ) ;
53+ } ;
54+ Accumulator . prototype . current = function ( ) { return this . stdout . contents ; }
55+ Accumulator . prototype . finish = function ( err ) { return [ err , this . stdout . contents , this . stderr . contents ] ; } ;
56+
57+ var std = options . output != null ? new Wrapper ( options . output ) : new Accumulator ( ) ;
58+
3059 var timeoutId ;
3160 if ( options . timeout > 0 ) {
3261 timeoutId = setTimeout ( function ( ) {
@@ -42,44 +71,20 @@ function exec2(file, args /*, options, callback */) {
4271 child . stdout . setEncoding ( options . encoding ) ;
4372 child . stderr . setEncoding ( options . encoding ) ;
4473
45- child . stdout . addListener ( "data" , function ( chunk ) {
46- if ( outputToStream ) {
47- stdout . write ( chunk , options . encoding ) ;
48- } else {
49- stdout += chunk ;
50- }
51- if ( ! killed && stdout . length > options . maxBuffer ) {
52- child . kill ( options . killSignal ) ;
53- killed = true ;
54- }
55- } ) ;
56-
57- child . stderr . addListener ( "data" , function ( chunk ) {
58- stderr += chunk ;
59- if ( ! killed && stderr . length > options . maxBuffer ) {
60- child . kill ( options . killSignal ) ;
61- killed = true
62- }
63- } ) ;
74+ child . stdout . addListener ( "data" , function ( chunk ) { std . out ( chunk , options . encoding ) ; } ) ;
75+ child . stderr . addListener ( "data" , function ( chunk ) { std . err ( chunk , options . encoding ) ; } ) ;
6476
6577 child . addListener ( "exit" , function ( code , signal ) {
6678 if ( timeoutId ) clearTimeout ( timeoutId ) ;
6779 if ( code === 0 && signal === null ) {
68- if ( callback ) {
69- if ( outputToStream ) {
70- stdout . end ( ) ;
71- callback ( null , stderr ) ;
72- } else {
73- callback ( null , stdout , stderr ) ;
74- }
75- }
80+ if ( callback ) callback . apply ( undefined , std . finish ( null ) ) ;
7681 } else {
7782 var e = new Error ( "Command " + ( timedOut ? "timed out" : "failed" ) + ": " + stderr ) ;
7883 e . timedOut = timedOut ;
7984 e . killed = killed ;
8085 e . code = code ;
8186 e . signal = signal ;
82- if ( callback ) callback ( e , stdout , stderr ) ;
87+ if ( callback ) callback . apply ( undefined , std . finish ( e ) ) ;
8388 }
8489 } ) ;
8590
0 commit comments