@@ -25,14 +25,26 @@ exports.useColors = useColors;
2525
2626exports . colors = [ 6 , 2 , 3 , 4 , 5 , 1 ] ;
2727
28+ /**
29+ * The file descriptor to write the `debug()` calls to.
30+ * Set the `DEBUG_FD` env variable to override with another value. i.e.:
31+ *
32+ * $ DEBUG_FD=3 node script.js 3>debug.log
33+ */
34+
35+ var fd = parseInt ( process . env . DEBUG_FD , 10 ) || 2 ;
36+ var stream = 1 === fd ? process . stdout :
37+ 2 === fd ? process . stderr :
38+ createWritableStdioStream ( fd ) ;
39+
2840/**
2941 * Is stdout a TTY? Colored output is enabled when `true`.
3042 */
3143
3244function useColors ( ) {
3345 var debugColors = ( process . env . DEBUG_COLORS || '' ) . trim ( ) . toLowerCase ( ) ;
3446 if ( 0 === debugColors . length ) {
35- return tty . isatty ( 1 ) ;
47+ return tty . isatty ( fd ) ;
3648 } else {
3749 return '0' !== debugColors
3850 && 'no' !== debugColors
@@ -91,7 +103,7 @@ function formatArgs() {
91103 */
92104
93105function log ( ) {
94- return console . error . apply ( console , arguments ) ;
106+ return stream . write ( util . format . apply ( this , arguments ) + '\n' ) ;
95107}
96108
97109/**
@@ -122,6 +134,74 @@ function load() {
122134 return process . env . DEBUG ;
123135}
124136
137+ /**
138+ * Copied from `node/src/node.js`.
139+ *
140+ * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
141+ * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
142+ */
143+
144+ function createWritableStdioStream ( fd ) {
145+ var stream ;
146+ var tty_wrap = process . binding ( 'tty_wrap' ) ;
147+
148+ // Note stream._type is used for test-module-load-list.js
149+
150+ switch ( tty_wrap . guessHandleType ( fd ) ) {
151+ case 'TTY' :
152+ stream = new tty . WriteStream ( fd ) ;
153+ stream . _type = 'tty' ;
154+
155+ // Hack to have stream not keep the event loop alive.
156+ // See https://github.com/joyent/node/issues/1726
157+ if ( stream . _handle && stream . _handle . unref ) {
158+ stream . _handle . unref ( ) ;
159+ }
160+ break ;
161+
162+ case 'FILE' :
163+ var fs = require ( 'fs' ) ;
164+ stream = new fs . SyncWriteStream ( fd , { autoClose : false } ) ;
165+ stream . _type = 'fs' ;
166+ break ;
167+
168+ case 'PIPE' :
169+ case 'TCP' :
170+ var net = require ( 'net' ) ;
171+ stream = new net . Socket ( {
172+ fd : fd ,
173+ readable : false ,
174+ writable : true
175+ } ) ;
176+
177+ // FIXME Should probably have an option in net.Socket to create a
178+ // stream from an existing fd which is writable only. But for now
179+ // we'll just add this hack and set the `readable` member to false.
180+ // Test: ./node test/fixtures/echo.js < /etc/passwd
181+ stream . readable = false ;
182+ stream . read = null ;
183+ stream . _type = 'pipe' ;
184+
185+ // FIXME Hack to have stream not keep the event loop alive.
186+ // See https://github.com/joyent/node/issues/1726
187+ if ( stream . _handle && stream . _handle . unref ) {
188+ stream . _handle . unref ( ) ;
189+ }
190+ break ;
191+
192+ default :
193+ // Probably an error on in uv_guess_handle()
194+ throw new Error ( 'Implement me. Unknown stream file type!' ) ;
195+ }
196+
197+ // For supporting legacy API we put the FD here.
198+ stream . fd = fd ;
199+
200+ stream . _isStdio = true ;
201+
202+ return stream ;
203+ }
204+
125205/**
126206 * Enable namespaces listed in `process.env.DEBUG` initially.
127207 */
0 commit comments