var util = require('util'); var EventEmitter = require('events').EventEmitter; var Stream = require('net').Stream; var InternalChildProcess = process.binding('child_process').ChildProcess; var constants; var spawn = exports.spawn = function (path, args){ var child = new ChildProcess(); child.spawn.apply(child, arguments); return child; } ; exports.exec = function (command){ var _slice = Array.prototype.slice; var args = ['/bin/sh', ['-c', command] ] .concat(_slice.call(arguments, 1)); return exports.execFile.apply(this, args); } ; exports.execFile = function (file){ var options = { encoding: 'utf8', timeout: 0, maxBuffer: 200 * 1024, killSignal: 'SIGTERM', cwd: null , env: null } ; var args, optionArg, callback; if (typeof arguments[_AN_Read_length('length', arguments) - 1] === 'function') { callback = arguments[_AN_Read_length('length', arguments) - 1]; } if (Array.isArray(arguments[1])) { args = arguments[1]; if (typeof arguments[2] === 'object') optionArg = arguments[2]; } else { args = [] ; if (typeof arguments[1] === 'object') optionArg = arguments[1]; } if (optionArg) { var keys = Object.keys(options); for (var i = 0, len = _AN_Read_length('length', keys); i < len; i++ ){ var k = keys[i]; if (optionArg[k] !== undefined) options[k] = optionArg[k]; } } var child = spawn(file, args, { cwd: options.cwd, env: options.env} ); var stdout = ''; var stderr = ''; var killed = false ; var exited = false ; var timeoutId; function exithandler(code, signal){ if (exited) return ; exited = true ; if (timeoutId) { clearTimeout(timeoutId); timeoutId = null ; } if (!callback) return ; if (code === 0 && signal === null ) { callback(null , stdout, stderr); } else { var e = new Error('Command failed: ' + stderr); e.killed = child.killed || killed; e.code = code; e.signal = signal; callback(e, stdout, stderr); } } function kill(){ killed = true ; child.kill(options.killSignal); process.nextTick(function (){ exithandler(null , options.killSignal); } ); } if (options.timeout > 0) { timeoutId = _AN_Call_settimeout('setTimeout', window, function (){ kill(); timeoutId = null ; } , options.timeout); } child.stdout.setEncoding(options.encoding); child.stderr.setEncoding(options.encoding); child.stdout.addListener('data', function (chunk){ stdout += chunk; if (_AN_Read_length('length', stdout) > options.maxBuffer) { kill(); } } ); child.stderr.addListener('data', function (chunk){ stderr += chunk; if (_AN_Read_length('length', stderr) > options.maxBuffer) { kill(); } } ); child.addListener('exit', exithandler); return child; } ; function ChildProcess(){ EventEmitter.call(this); var self = this; this.killed = false ; var gotCHLD = false ; var exitCode; var termSignal; var internal = this._internal = new InternalChildProcess(); var stdin = this.stdin = new Stream(); var stdout = this.stdout = new Stream(); var stderr = this.stderr = new Stream(); var stderrClosed = false ; var stdoutClosed = false ; stderr.addListener('close', function (){ stderrClosed = true ; if (gotCHLD && (!self.stdout || stdoutClosed)) { self.emit('exit', exitCode, termSignal); } } ); stdout.addListener('close', function (){ stdoutClosed = true ; if (gotCHLD && (!self.stderr || stderrClosed)) { self.emit('exit', exitCode, termSignal); } } ); internal.onexit = function (code, signal){ gotCHLD = true ; exitCode = code; termSignal = signal; if (self.stdin) { self.stdin.end(); } if ((!self.stdout || !self.stdout.readable) && (!self.stderr || !self.stderr.readable)) { self.emit('exit', exitCode, termSignal); } } ; this.__defineGetter__('pid', function (){ return internal.pid; } ); } util.inherits(ChildProcess, EventEmitter); ChildProcess.prototype.kill = function (sig){ if (this._internal.pid) { this.killed = true ; if (!constants) constants = process.binding('constants'); sig = sig || 'SIGTERM'; if (!constants[sig]) throw new Error('Unknown signal: ' + sig) return this._internal.kill(constants[sig]); } } ; ChildProcess.prototype.spawn = function (path, args, options, customFds){ args = args || [] ; var cwd, env; if (!options || options.cwd === undefined && options.env === undefined && options.customFds === undefined) { cwd = ''; env = options || process.env; customFds = customFds || [-1, -1, -1] ; } else { cwd = options.cwd || ''; env = options.env || process.env; customFds = options.customFds || [-1, -1, -1] ; } var envPairs = [] ; var keys = Object.keys(env); for (var index = 0, keysLength = _AN_Read_length('length', keys); index < keysLength; index++ ){ var key = keys[index]; envPairs.push(key + '=' + env[key]); } var fds = this._internal.spawn(path, args, cwd, envPairs, customFds); this.fds = fds; if (customFds[0] === -1 || customFds[0] === undefined) { _AN_Call_open('open', this.stdin, fds[0]); this.stdin.writable = true ; this.stdin.readable = false ; } else { this.stdin = null ; } if (customFds[1] === -1 || customFds[1] === undefined) { _AN_Call_open('open', this.stdout, fds[1]); this.stdout.writable = false ; this.stdout.readable = true ; this.stdout.resume(); } else { this.stdout = null ; } if (customFds[2] === -1 || customFds[2] === undefined) { _AN_Call_open('open', this.stderr, fds[2]); this.stderr.writable = false ; this.stderr.readable = true ; this.stderr.resume(); } else { this.stderr = null ; } } ;