Skip to content

Commit

Permalink
treekill implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
jshkurti committed Oct 9, 2014
1 parent 02d47e8 commit fe92e71
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/God/Methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
var p = require('path');
var Common = require('../Common');
var treekill = require('../TreeKill');
/**
* Description
* @method exports
Expand Down Expand Up @@ -210,7 +211,7 @@ module.exports = function(God) {
if (!pid) return cb({msg : 'no pid passed or null'});

try {
process.kill(pid, 'SIGINT');
treekill(pid);
} catch(e) {
console.error('%s pid can not be killed', pid, e);
return cb({type : 'kill', msg : pid + ' can not be killed'});
Expand Down
109 changes: 109 additions & 0 deletions lib/TreeKill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**!
* treekill - index.js
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*
* 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';

module.exports = treekill;

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

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

function killAll(tree, signal) {
var killed = {};
Object.keys(tree).forEach(function (pid) {
tree[pid].forEach(function (pidpid) {
if (!killed[pidpid]) {
killPid(pidpid, signal);
killed[pidpid] = 1;
}
});
if (!killed[pid]) {
killPid(pid, signal);
killed[pid] = 1;
}
});
}

function killPid(pid, signal) {
try {
process.kill(parseInt(pid), signal);
} catch (err) {
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();
});
});
delete pidsToProcess[ppid];

var pids = [];
for (var i = 0; i < lines.length; i++) {
var item = lines[i];
if (item[1] === ppid) {
pids.push(parseInt(item[0]));
}
}

if (pids.length === 0 && Object.keys(pidsToProcess).length === 0) {
return cb();
}

pids.forEach(function (pid) {
tree[ppid].push(pid);
tree[pid] = [];
pidsToProcess[pid] = 1;
buildProcessTree(pid, tree, pidsToProcess, cb);
});
});
}

0 comments on commit fe92e71

Please sign in to comment.