Skip to content

Commit

Permalink
Reference treekill lib from the original one but not a copy, and ma…
Browse files Browse the repository at this point in the history
…ke it works more stabler && highly performance.
  • Loading branch information
Tjatse committed Nov 28, 2014
1 parent 2cc824c commit 11fe5f4
Showing 1 changed file with 69 additions and 68 deletions.
137 changes: 69 additions & 68 deletions lib/TreeKill.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
/**!
* treekill - index.js
/**
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
* Reference: https://github.com/pkrumins/node-tree-kill
* Author : pkrumins
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
* Update : PM2 team
*
* Github:
* https://github.com/node-modules/treekill
*/

/**
* Module dependencies.
*/

var childProcess = require('child_process');
var spawn = childProcess.spawn;
var exec = childProcess.exec;
var isWindows = process.platform === 'win32';
var isDarwin = process.platform === 'darwin';
var exec = require('child_process').exec,
isWin = process.platform === 'win32',
downgradePs = false;

module.exports = treekill;

function treekill(pid, signal, callback) {
if (typeof signal === 'function') {
callback = signal;
signal = null;
}

if (isWindows) {
module.exports = function(pid, signal){
if (isWin) {
exec('taskkill /pid ' + pid + ' /T /F');
} else {
var tree = {};
tree[pid] = [];
var pidsToProcess = {};
pidsToProcess[pid] = 1;
buildProcessTree(pid, tree, pidsToProcess, function () {
var tree = {}, pidsToProcess = {};
buildProcessTree(pid, tree, pidsToProcess, function(){
killAll(tree, signal);
if (typeof callback === 'function') {
callback();
}
});
}
}

function killAll(tree, signal) {
function killAll(tree, signal){
var killed = {};
Object.keys(tree).forEach(function (pid) {
tree[pid].forEach(function (pidpid) {
Object.keys(tree).forEach(function(pid){
tree[pid].forEach(function(pidpid){
if (!killed[pidpid]) {
killPid(pidpid, signal);
killed[pidpid] = 1;
Expand All @@ -61,49 +38,73 @@ function killAll(tree, signal) {
});
}

function killPid(pid, signal) {
function killPid(pid, signal){
try {
process.kill(parseInt(pid), signal);
} catch (err) {
if (err.code !== 'ESRCH') {
process.kill(pid, signal);
}
catch (err) {
if (err.code == 'EINVAL'){
throw new Error('The value of the sig argument is an invalid or unsupported signal number.');
}
if(err.code == 'EPERM'){
throw new Error('The process does not have permission to send the signal to any receiving process.');
}
if (err.code !== 'ESRCH'){
throw err;
}
}
}

function buildProcessTree(ppid, tree, pidsToProcess, cb) {
var cmd = 'ps -e -o pid,ppid';
ppid = String(ppid);
exec(cmd, function (err, stdout, stderr) {
if (err) {
console.log(stderr);
throw err;
}
var lines = stdout.toString().split('\n');
lines = lines.map(function (line) {
return line.trim().split(/ +/).map(function (item) {
return item.trim();
});
});
function buildProcessTree(ppid, tree, pidsToProcess, cb){
pidsToProcess[ppid] = 1;
tree[ppid] = [];

function isFinish(){
delete pidsToProcess[ppid];
if(Object.keys(pidsToProcess).length == 0){
return cb();
}
}

var pids = [];
for (var i = 0; i < lines.length; i++) {
var item = lines[i];
if (item[1] === ppid) {
pids.push(parseInt(item[0]));
var args = downgradePs ? '-eo pid,ppid | grep -w ' : '-o pid --no-headers --ppid ';
var ps = exec('ps ' + args + ppid, function(err, stdout, stderr){
if (err) {
// illegal option --, try to use basic `ps` instead of it.
if (/illegal/.test(err.message) && !downgradePs) {
downgradePs = true;
return buildProcessTree(ppid, tree, pidsToProcess, cb);
}
}

if (pids.length === 0 && Object.keys(pidsToProcess).length === 0) {
return cb();
// Avoid pipe close error - dynamic self-closing process.
if(/Command failed/.test(err.message)) {
return isFinish();
}
throw err;
}

pids.forEach(function (pid) {
tree[ppid].push(pid);
tree[pid] = [];
pidsToProcess[pid] = 1;
buildProcessTree(pid, tree, pidsToProcess, cb);
var pids = stdout.split('\n');

// remove parentPid if necessary.
downgradePs && pids.shift();

pids = pids.filter(function(pid){
return !!pid;
}).map(function(pid){
pid = pid.trim();
return parseInt(downgradePs ? pid.slice(0, pid.search(/\s/)) : pid, 10);
});

if(pids.length > 0){
tree[ppid] = tree[ppid].concat(pids);
pids.forEach(function(pid){
if(!tree[pid]) {
buildProcessTree(pid, tree, pidsToProcess, cb);
}else{
delete pidsToProcess[pid];
}
});
}

isFinish();
});
}

0 comments on commit 11fe5f4

Please sign in to comment.