-
Notifications
You must be signed in to change notification settings - Fork 32
/
index.js
122 lines (109 loc) · 3.16 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
'use strict';
var spawn = require('child_process').spawn,
es = require('event-stream');
module.exports = function childrenOfPid(pid, callback) {
var headers = null;
if (typeof callback !== 'function') {
throw new Error('childrenOfPid(pid, callback) expects callback');
}
if (typeof pid === 'number') {
pid = pid.toString();
}
//
// The `ps-tree` module behaves differently on *nix vs. Windows
// by spawning different programs and parsing their output.
//
// Linux:
// 1. " <defunct> " need to be striped
// ```bash
// $ ps -A -o comm,ppid,pid,stat
// COMMAND PPID PID STAT
// bbsd 2899 16958 Ss
// watch <defunct> 1914 16964 Z
// ps 20688 16965 R+
// ```
//
// Darwin:
// $ ps -A -o comm,ppid,pid,stat
// COMM PPID PID STAT
// /sbin/launchd 0 1 Ss
// /usr/libexec/Use 1 43 Ss
//
// Win32:
// 1. wmic PROCESS WHERE ParentProcessId=4604 GET Name,ParentProcessId,ProcessId,Status)
// 2. The order of head columns is fixed
// ```shell
// > wmic PROCESS GET Name,ProcessId,ParentProcessId,Status
// Name ParentProcessId ProcessId Status
// System Idle Process 0 0
// System 0 4
// smss.exe 4 228
// ```
var processLister;
if (process.platform === 'win32') {
// See also: https://github.com/nodejs/node-v0.x-archive/issues/2318
processLister = spawn('wmic.exe', ['PROCESS', 'GET', 'Name,ProcessId,ParentProcessId,Status']);
} else {
processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm']);
}
es.connect(
// spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm']).stdout,
processLister.stdout,
es.split(),
es.map(function (line, cb) { //this could parse alot of unix command output
var columns = line.trim().split(/\s+/);
if (!headers) {
headers = columns;
//
// Rename Win32 header name, to as same as the linux, for compatible.
//
headers = headers.map(normalizeHeader);
return cb();
}
var row = {};
// For each header
var h = headers.slice();
while (h.length) {
row[h.shift()] = h.length ? columns.shift() : columns.join(' ');
}
return cb(null, row);
}),
es.writeArray(function (err, ps) {
var parents = {},
children = [];
parents[pid] = true;
ps.forEach(function (proc) {
if (parents[proc.PPID]) {
parents[proc.PID] = true;
children.push(proc)
}
});
callback(null, children);
})
).on('error', callback)
}
/**
* Normalizes the given header `str` from the Windows
* title to the *nix title.
*
* @param {string} str Header string to normalize
*/
function normalizeHeader(str) {
switch (str) {
case 'Name': // for win32
case 'COMM': // for darwin
return 'COMMAND';
break;
case 'ParentProcessId':
return 'PPID';
break;
case 'ProcessId':
return 'PID';
break;
case 'Status':
return 'STAT';
break;
default:
return str
}
}