Browse Source

Fix child_process.kill oddities

* When the process is already dead, but the `exit` signal wasn't raised
  yet, the ESRCH error should be ignored.

* When an invalid signal is specified, kill() should throw.

* Like process.kill(), child_process.kill() now preserves a `0` signal
  which can be used to check the liveliness of the child process.

* process.kill() and child_process.kill() will now return true if the
  signal was actually delivered, and false otherwise.

* When an `exec`-ed process is automatically killed because a time or
  buffer limit is exceeded, and the kill() fails, this error should be
  reported through the `exec` callback.

Fixes: #3409
v0.9.1-release
Bert Belder 13 years ago
parent
commit
10f85fadfe
  1. 51
      lib/child_process.js
  2. 2
      src/node.js

51
lib/child_process.js

@ -536,12 +536,24 @@ exports.execFile = function(file /* args, options, callback */) {
} }
} }
function errorhandler(e) {
err = e;
child.stdout.destroy();
child.stderr.destroy();
exithandler();
}
function kill() { function kill() {
child.stdout.destroy();
child.stderr.destroy();
killed = true; killed = true;
child.kill(options.killSignal); try {
process.nextTick(function() { child.kill(options.killSignal);
exithandler(null, options.killSignal); } catch (e) {
}); err = e;
exithandler();
}
} }
if (options.timeout > 0) { if (options.timeout > 0) {
@ -571,6 +583,7 @@ exports.execFile = function(file /* args, options, callback */) {
}); });
child.addListener('close', exithandler); child.addListener('close', exithandler);
child.addListener('error', errorhandler);
return child; return child;
}; };
@ -822,25 +835,43 @@ function errnoException(errorno, syscall, errmsg) {
ChildProcess.prototype.kill = function(sig) { ChildProcess.prototype.kill = function(sig) {
var signal;
if (!constants) { if (!constants) {
constants = process.binding('constants'); constants = process.binding('constants');
} }
sig = sig || 'SIGTERM'; if (sig === 0) {
var signal = constants[sig]; signal = 0;
} else if (!sig) {
signal = constants['SIGTERM'];
} else {
signal = constants[sig];
}
if (!signal) { if (signal === undefined) {
throw new Error('Unknown signal: ' + sig); throw new Error('Unknown signal: ' + sig);
} }
if (this._handle) { if (this._handle) {
this.killed = true;
var r = this._handle.kill(signal); var r = this._handle.kill(signal);
if (r === -1) { if (r == 0) {
/* Success. */
this.killed = true;
return true;
} else if (errno == 'ESRCH') {
/* Already dead. */
} else if (errno == 'EINVAL' || errno == 'ENOSYS') {
/* The underlying platform doesn't support this signal. */
throw errnoException(errno, 'kill');
} else {
/* Other error, almost certainly EPERM. */
this.emit('error', errnoException(errno, 'kill')); this.emit('error', errnoException(errno, 'kill'));
return;
} }
} }
/* Kill didn't succeed. */
return false;
}; };

2
src/node.js

@ -430,6 +430,8 @@
if (r) { if (r) {
throw errnoException(errno, 'kill'); throw errnoException(errno, 'kill');
} }
return true;
}; };
}; };

Loading…
Cancel
Save