mirror of https://github.com/nodejs/node.git
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: #3409pull/24503/head
parent
b53b8b8ae7
commit
10f85fadfe
|
@ -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() {
|
||||
child.stdout.destroy();
|
||||
child.stderr.destroy();
|
||||
|
||||
killed = true;
|
||||
child.kill(options.killSignal);
|
||||
process.nextTick(function() {
|
||||
exithandler(null, options.killSignal);
|
||||
});
|
||||
try {
|
||||
child.kill(options.killSignal);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
exithandler();
|
||||
}
|
||||
}
|
||||
|
||||
if (options.timeout > 0) {
|
||||
|
@ -571,6 +583,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||
});
|
||||
|
||||
child.addListener('close', exithandler);
|
||||
child.addListener('error', errorhandler);
|
||||
|
||||
return child;
|
||||
};
|
||||
|
@ -822,25 +835,43 @@ function errnoException(errorno, syscall, errmsg) {
|
|||
|
||||
|
||||
ChildProcess.prototype.kill = function(sig) {
|
||||
var signal;
|
||||
|
||||
if (!constants) {
|
||||
constants = process.binding('constants');
|
||||
}
|
||||
|
||||
sig = sig || 'SIGTERM';
|
||||
var signal = constants[sig];
|
||||
if (sig === 0) {
|
||||
signal = 0;
|
||||
} else if (!sig) {
|
||||
signal = constants['SIGTERM'];
|
||||
} else {
|
||||
signal = constants[sig];
|
||||
}
|
||||
|
||||
if (!signal) {
|
||||
if (signal === undefined) {
|
||||
throw new Error('Unknown signal: ' + sig);
|
||||
}
|
||||
|
||||
if (this._handle) {
|
||||
this.killed = true;
|
||||
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'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill didn't succeed. */
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -430,6 +430,8 @@
|
|||
if (r) {
|
||||
throw errnoException(errno, 'kill');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue