UNPKG

2.77 kBJavaScriptView Raw
1'use strict';
2
3// From https://raw.githubusercontent.com/pkrumins/node-tree-kill/master/index.js
4
5var childProcess = require('child_process');
6var spawn = childProcess.spawn;
7var exec = childProcess.exec;
8
9module.exports = function (pid, signal, callback) {
10 var tree = {};
11 var pidsToProcess = {};
12 tree[pid] = [];
13 pidsToProcess[pid] = 1;
14
15 switch (process.platform) {
16 case 'win32':
17 exec('taskkill /pid ' + pid + ' /T /F', { windowsHide: true }, callback);
18 break;
19 case 'darwin':
20 buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
21 return spawn('pgrep', ['-P', parentPid]);
22 }, function () {
23 killAll(tree, signal, callback);
24 });
25 break;
26 // case 'sunos':
27 // buildProcessTreeSunOS(pid, tree, pidsToProcess, function () {
28 // killAll(tree, signal, callback);
29 // });
30 // break;
31 default: // Linux
32 buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
33 return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]);
34 }, function () {
35 killAll(tree, signal, callback);
36 });
37 break;
38 }
39};
40
41function killAll (tree, signal, callback) {
42 var killed = {};
43 try {
44 Object.keys(tree).forEach(function (pid) {
45 tree[pid].forEach(function (pidpid) {
46 if (!killed[pidpid]) {
47 killPid(pidpid, signal);
48 killed[pidpid] = 1;
49 }
50 });
51 if (!killed[pid]) {
52 killPid(pid, signal);
53 killed[pid] = 1;
54 }
55 });
56 } catch (err) {
57 if (callback) {
58 return callback(err);
59 } else {
60 console.error(err);
61 }
62 }
63 if (callback) {
64 return callback();
65 }
66}
67
68function killPid(pid, signal) {
69 try {
70 process.kill(parseInt(pid, 10), signal);
71 }
72 catch (err) {
73 if (err.code !== 'ESRCH')
74 console.error(err);
75 }
76}
77
78function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesList, cb) {
79 var ps = spawnChildProcessesList(parentPid);
80 var allData = '';
81
82 ps.on('error', function(err) {
83 console.error(err);
84 });
85
86 if (ps.stdout) {
87 ps.stdout.on('data', function (data) {
88 data = data.toString('ascii');
89 allData += data;
90 });
91 }
92
93 var onClose = function (code) {
94 delete pidsToProcess[parentPid];
95
96 if (code !== 0) {
97 // no more parent processes
98 if (Object.keys(pidsToProcess).length == 0) {
99 cb();
100 }
101 return;
102 }
103 var pids = allData.match(/\d+/g) || [];
104 if (pids.length === 0)
105 return cb();
106
107 pids.forEach(function (pid) {
108 pid = parseInt(pid, 10);
109 tree[parentPid].push(pid);
110 tree[pid] = [];
111 pidsToProcess[pid] = 1;
112 buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb);
113 });
114 };
115
116 ps.on('close', onClose);
117}