Browse Source

Prevents child_process.exec timeouts from throwing when the child was previously killed.

v0.7.4-release
Aaron Heckmann 14 years ago
committed by Ryan Dahl
parent
commit
bd8e4f656e
  1. 34
      lib/child_process.js
  2. 13
      test/simple/test-exec.js

34
lib/child_process.js

@ -62,14 +62,23 @@ exports.execFile = function (file /* args, options, callback */) {
var stderr = "";
var killed = false;
function kill(){
if (killed) return;
try {
child.kill(options.killSignal);
} catch (err) {
if ("No such process" !== err.message) {
throw err;
}
}
killed = true;
}
var timeoutId;
if (options.timeout > 0) {
timeoutId = setTimeout(function () {
if (!killed) {
child.kill(options.killSignal);
killed = true;
timeoutId = null;
}
kill();
timeoutId = null;
}, options.timeout);
}
@ -78,30 +87,29 @@ exports.execFile = function (file /* args, options, callback */) {
child.stdout.addListener("data", function (chunk) {
stdout += chunk;
if (!killed && stdout.length > options.maxBuffer) {
child.kill(options.killSignal);
killed = true;
if (stdout.length > options.maxBuffer) {
kill();
}
});
child.stderr.addListener("data", function (chunk) {
stderr += chunk;
if (!killed && stderr.length > options.maxBuffer) {
child.kill(options.killSignal);
killed = true;
if (stderr.length > options.maxBuffer) {
kill();
}
});
child.addListener("exit", function (code, signal) {
if (timeoutId) clearTimeout(timeoutId);
if (!callback) return;
if (code === 0 && signal === null) {
if (callback) callback(null, stdout, stderr);
callback(null, stdout, stderr);
} else {
var e = new Error("Command failed: " + stderr);
e.killed = killed;
e.code = code;
e.signal = signal;
if (callback) callback(e, stdout, stderr);
callback(e, stdout, stderr);
}
});

13
test/simple/test-exec.js

@ -35,12 +35,23 @@ exec("ls /DOES_NOT_EXIST", function (err, stdout, stderr) {
}
});
exec("sleep 10", { timeout: 50 }, function (err, stdout, stderr) {
exec("sleep 3", { timeout: 50 }, function (err, stdout, stderr) {
assert.ok(err);
assert.ok(err.killed);
assert.equal(err.signal, 'SIGKILL');
});
var killMeTwice = exec("sleep 3", { timeout: 1000 }, function killMeTwiceCallback(err, stdout, stderr) {
assert.ok(err);
assert.ok(err.killed);
assert.equal(err.signal, 'SIGTERM');
});
process.nextTick(function(){
killMeTwice.kill();
});
exec('python -c "print 200000*\'C\'"', { maxBuffer: 1000 }, function (err, stdout, stderr) {
assert.ok(err);
assert.ok(err.killed);

Loading…
Cancel
Save