|
@ -11,22 +11,64 @@ var spawn = exports.spawn = function (path, args, env) { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
exports.exec = function (command, callback) { |
|
|
exports.exec = function (command /* , options, callback */) { |
|
|
|
|
|
var options = { encoding: 'utf8' |
|
|
|
|
|
, timeout: 0 |
|
|
|
|
|
, maxBuffer: 200*1024 |
|
|
|
|
|
, killSignal: 'SIGKILL' |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var callback = arguments[arguments.length-1]; |
|
|
|
|
|
if (typeof arguments[1] == 'object') { |
|
|
|
|
|
var keys = Object.keys(options); |
|
|
|
|
|
for (var i = 0; i < keys.length; i++) { |
|
|
|
|
|
var k = keys[i]; |
|
|
|
|
|
if (arguments[1][k] !== undefined) options[k] = arguments[1][k]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var child = spawn("/bin/sh", ["-c", command]); |
|
|
var child = spawn("/bin/sh", ["-c", command]); |
|
|
var stdout = ""; |
|
|
var stdout = ""; |
|
|
var stderr = ""; |
|
|
var stderr = ""; |
|
|
|
|
|
var killed = false; |
|
|
|
|
|
|
|
|
|
|
|
var timeoutId; |
|
|
|
|
|
if (options.timeout > 0) { |
|
|
|
|
|
timeoutId = setTimeout(function () { |
|
|
|
|
|
if (!killed) { |
|
|
|
|
|
child.kill(options.killSignal); |
|
|
|
|
|
killed = true; |
|
|
|
|
|
timeoutId = null; |
|
|
|
|
|
} |
|
|
|
|
|
}, options.timeout); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
child.stdout.setEncoding('utf8'); |
|
|
child.stdout.setEncoding(options.encoding); |
|
|
child.stdout.addListener("data", function (chunk) { stdout += chunk; }); |
|
|
child.stderr.setEncoding(options.encoding); |
|
|
|
|
|
|
|
|
child.stderr.setEncoding('utf8'); |
|
|
child.stdout.addListener("data", function (chunk) { |
|
|
child.stderr.addListener("data", function (chunk) { stderr += chunk; }); |
|
|
stdout += chunk; |
|
|
|
|
|
if (!killed && stdout.length > options.maxBuffer) { |
|
|
|
|
|
child.kill(options.killSignal); |
|
|
|
|
|
killed = true; |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
child.stderr.addListener("data", function (chunk) { |
|
|
|
|
|
stderr += chunk; |
|
|
|
|
|
if (!killed && stderr.length > options.maxBuffer) { |
|
|
|
|
|
child.kill(options.killSignal); |
|
|
|
|
|
killed = true |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
child.addListener("exit", function (code) { |
|
|
child.addListener("exit", function (code) { |
|
|
|
|
|
if (timeoutId) clearTimeout(timeoutId); |
|
|
if (code == 0) { |
|
|
if (code == 0) { |
|
|
if (callback) callback(null, stdout, stderr); |
|
|
if (callback) callback(null, stdout, stderr); |
|
|
} else { |
|
|
} else { |
|
|
var e = new Error("Command failed: " + stderr); |
|
|
var e = new Error("Command failed: " + stderr); |
|
|
|
|
|
e.killed = killed; |
|
|
e.code = code; |
|
|
e.code = code; |
|
|
if (callback) callback(e, stdout, stderr); |
|
|
if (callback) callback(e, stdout, stderr); |
|
|
} |
|
|
} |
|
|