Socket
Socket
Sign inDemoInstall

pidtree

Package Overview
Dependencies
0
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.0 to 0.3.0

lib/get.js

117

bin/pidtree.js

@@ -6,17 +6,110 @@ #!/usr/bin/env node

var os = require('os');
var pidtree = require('..');
//
// Change the default parent PID if running
// under Windows.
//
let ppid = 1;
if (process.platform === 'win32') {
ppid = 0;
function help() {
var help = ` Usage
$ pidtree <ppid>
Options
--list To print the pids as a list.
Examples
$ pidtree
$ pidtree --list
$ pidtree 1
$ pidtree 1 --list
`;
console.log(help);
}
require('..')(process.argv[2] || ppid, (err, data) => {
if (err) {
return console.error(err);
function list(ppid) {
pidtree(ppid === undefined ? -1 : ppid, function(err, list) {
if (err) {
console.error(err.message);
return;
}
console.log(list.join(os.EOL));
});
}
function tree(ppid) {
pidtree(ppid, {advanced: true}, function(err, list) {
if (err) {
console.error(err.message);
return;
}
var parents = {}; // Hash Map of parents
var tree = {}; // Adiacency Hash Map
while (list.length > 0) {
var e = list.pop();
if (tree[e.ppid]) {
tree[e.ppid].push(e.pid);
} else {
tree[e.ppid] = [e.pid];
}
if (ppid === -1) {
parents[e.pid] = e.ppid;
}
}
var roots = [ppid];
if (ppid === -1) {
// Get all the roots
roots = Object.keys(tree).filter(node => parents[node] === undefined);
}
roots.forEach(root => print(tree, root));
});
function print(tree, start) {
function printBranch(node, branch) {
const isGraphHead = branch.length === 0;
const children = tree[node] || [];
let branchHead = '';
if (!isGraphHead) {
branchHead = children.length > 0 ? '┬ ' : '─ ';
}
console.log(`${branch}${branchHead}${node}`);
var baseBranch = branch;
if (!isGraphHead) {
const isChildOfLastBranch = branch.slice(-2) === '└─';
baseBranch = branch.slice(0, -2) + (isChildOfLastBranch ? ' ' : '| ');
}
const nextBranch = baseBranch + '├─';
const lastBranch = baseBranch + '└─';
children.forEach((child, index) => {
printBranch(
child,
children.length - 1 === index ? lastBranch : nextBranch
);
});
}
printBranch(start, '');
}
console.log(data.join(os.EOL));
});
}
function run() {
var flag;
var ppid;
for (var i = 2; i < process.argv.length; i++) {
if (process.argv[i].startsWith('--')) {
flag = process.argv[i];
} else {
ppid = process.argv[i];
}
}
if (ppid === undefined) {
ppid = -1;
}
if (flag === '--list') list(ppid);
else if (flag === undefined) tree(ppid);
else help();
}
run();

20

index.js

@@ -12,15 +12,17 @@ 'use strict';

var tree = require('./lib/tree');
var pidtree = require('./lib/pidtree');
/**
* Get the list of child pids of the given pid.
* Get the list of children pids of the given pid.
* @public
* @param {Number|String} pid A pid.
* @param {Number|String} PID A PID. If -1 will return all the pids.
* @param {Object} [options] Optional options object.
* @param {Boolean} [options.root=false] Include the provided pid in the list.
* @param {Boolean} [options.root=false] Include the provided PID in the list.
* @param {Boolean} [options.advanced=false] Returns a list of objects in the
* format {pid: X, ppid: Y}.
* @param {Function} [callback=undefined] Called when the list is ready. If not
* provided a promise is returned instead.
* @returns {Promise.<Object>} Only when the callback is not provided.
* @returns {Promise.<Object[]>} Only when the callback is not provided.
*/
function pidtree(pid, options, callback) {
function list(pid, options, callback) {
if (typeof options === 'function') {

@@ -31,8 +33,8 @@ callback = options;

if (typeof callback === 'function') {
tree(pid, options, callback);
pidtree(pid, options, callback);
return;
}
return pify(tree, pid, options);
return pify(pidtree, pid, options);
}
module.exports = pidtree;
module.exports = list;

@@ -7,75 +7,38 @@ 'use strict';

/**
* Get the list of child pids of the given pid through the ps command.
* @param {Number} pid
* @param {Function} done(err, tree)
* Gets the list of all the pids of the system through the ps command.
* @param {Function} callback(err, list)
*/
function ps(pid, done) {
var args = ['-A', '-o', 'pid,ppid'];
function ps(callback) {
var args = ['-A', '-o', 'ppid,pid'];
bin('ps', args, function(err, stdout, code) {
if (err) return done(err);
if (err) return callback(err);
if (code !== 0) {
return done(new Error('pidtree ps command exited with code ' + code));
return callback(new Error('pidtree ps command exited with code ' + code));
}
// Example of stdout on *nix.
//
// PID PPID
// 430 1
// 432 430
// 727 1
// 7166 1
// Example of stdout on Darwin
// Example of stdout
//
// PID PPID
// 430 1
// 432 430
// 727 1
// 7166 1
// PPID PID
// 1 430
// 430 432
// 1 727
// 1 7166
stdout = stdout.split(os.EOL);
try {
stdout = stdout.split(os.EOL);
var found = false;
var tree = {};
for (var i = 1; i < stdout.length; i++) {
var line = stdout[i].trim().split(/\s+/);
if (!line || line.length !== 2) {
continue;
var list = [];
for (var i = 1; i < stdout.length; i++) {
stdout[i] = stdout[i].trim();
if (!stdout[i]) continue;
stdout[i] = stdout[i].split(/\s+/);
stdout[i][0] = parseInt(stdout[i][0], 10); // PPID
stdout[i][1] = parseInt(stdout[i][1], 10); // PID
list.push(stdout[i]);
}
var PID = parseInt(line[0], 10);
var PPID = parseInt(line[1], 10);
if (pid === PID || pid === PPID) {
found = true;
}
// Build the graph
if (tree[PPID]) {
tree[PPID].push(PID);
} else {
tree[PPID] = [PID];
}
callback(null, list);
} catch (err) {
callback(err);
}
if (!found) {
return done(new Error('No maching pid found'));
}
// Simplified BFS like tree visit
var idx = 0;
var pids = [pid];
while (idx < pids.length) {
var cur = pids[idx++];
if (!tree[cur]) continue;
var len = tree[cur].length;
for (var j = 0; j < len; j++) {
pids.push(tree[cur][j]);
}
delete tree[cur];
}
pids.shift(); // Remove root
done(null, pids);
});

@@ -82,0 +45,0 @@ }

@@ -7,7 +7,6 @@ 'use strict';

/**
* Get the list of child pids of the given pid through the wmic command.
* @param {Number} pid
* @param {Function} done(err, tree)
* Gets the list of all the pids of the system through the wmic command.
* @param {Function} callback(err, list)
*/
function wmic(pid, done) {
function wmic(callback) {
var args = ['PROCESS', 'get', 'ParentProcessId,ProcessId'];

@@ -17,8 +16,11 @@ var options = {windowsHide: true, windowsVerbatimArguments: true};

if (err) {
return done(err);
callback(err);
return;
}
if (code !== 0) {
return done(new Error('pidtree wmic command exited with code ' + code));
callback(new Error('pidtree wmic command exited with code ' + code));
return;
}
// Example of stdout on Windows 10
// Example of stdout
//

@@ -28,47 +30,18 @@ // ParentProcessId ProcessId

stdout = stdout.split(os.EOL);
try {
stdout = stdout.split(os.EOL);
var found = false;
var tree = {};
for (var i = 1; i < stdout.length; i++) {
var line = stdout[i].trim().split(/\s+/);
if (!line || line.length !== 2) {
continue;
var list = [];
for (var i = 1; i < stdout.length; i++) {
stdout[i] = stdout[i].trim();
if (!stdout[i]) continue;
stdout[i] = stdout[i].split(/\s+/);
stdout[i][0] = parseInt(stdout[i][0], 10); // PPID
stdout[i][1] = parseInt(stdout[i][1], 10); // PID
list.push(stdout[i]);
}
var PPID = parseInt(line[0], 10);
var PID = parseInt(line[1], 10);
if (pid === PID || pid === PPID) {
found = true;
}
// Build the graph
if (tree[PPID]) {
tree[PPID].push(PID);
} else {
tree[PPID] = [PID];
}
callback(null, list);
} catch (err) {
callback(err);
}
if (!found) {
return done(new Error('No maching pid found'));
}
// Simplified BFS like tree visit
var idx = 0;
var pids = [pid];
while (idx < pids.length) {
var cur = pids[idx++];
if (!tree[cur]) continue;
var len = tree[cur].length;
for (var j = 0; j < len; j++) {
pids.push(tree[cur][j]);
}
delete tree[cur];
}
pids.shift(); // Remove root
done(null, pids);
});

@@ -75,0 +48,0 @@ }

{
"name": "pidtree",
"version": "0.2.0",
"version": "0.3.0",
"description": "Cross platform children list of a PID",
"license": "MIT",
"homepage": "http://github.com/simonpri/pidtree#readme",
"repository": "github:simonpri/pidtree",
"homepage": "http://github.com/simonepri/pidtree#readme",
"repository": "github:simonepri/pidtree",
"bugs": {
"url": "https://github.com/simonpri/pidtree/issues",
"url": "https://github.com/simonepri/pidtree/issues",
"email": "simonepri@outlook.com"

@@ -16,3 +16,3 @@ },

],
"keyboards": [
"keywords": [
"ps-tree",

@@ -49,6 +49,8 @@ "ps",

"test": "npm run lint&& nyc ava -m \"!*benchmark*\"",
"bench": "ava -m \"*benchmark*\""
"bench": "ava -m \"*benchmark*\"",
"coverage": "codecov"
},
"devDependencies": {
"ava": "*",
"codecov": "*",
"mockery": "^2.1.0",

@@ -79,5 +81,6 @@ "np": "*",

"prefer-arrow-callback": 0,
"no-var": 0
"no-var": 0,
"object-shorthand": 0
}
}
}

@@ -70,6 +70,10 @@ <h1 align="center">

## Motivation
The only package that does this simple but tricky job is [ps-tree][gh:ps-tree]
but the project is unmaintained and furthermore the logic is wrong.
## Synopsis
This package is really similar to [ps-tree][gh:ps-tree] but is faster, safer and
provides sub-children results.
Furthermore ps-tree is [unmaintained][gh:ps-tree-um].
Uuh, and a fancy [CLI](#cli) is also available!
## Usage

@@ -92,12 +96,18 @@

// Get all the processes of the System on *nix
pidtree(1, function (err, pids) {
// Get all the processes of the System (-1 is a special value of this package)
pidtree(-1, function (err, pids) {
console.log(pids)
// => [41,45,43,530,47,50, ..., 41241, 32]
// => [530, 42, ..., 41241]
})
// Include PPID in the results
pidtree(1, {advanced: true}, function (err, pids) {
console.log(pids)
// => [{ppid: 1, pid: 530}, {ppid: 1, pid: 42}, ..., {ppid: 1, pid: 41241}]
})
// If no callback is given it returns a promise instead
const pids = await pidtree(1)
console.log(pids)
// => [41,45,43,530,47,50, ..., 41241, 32]
// => [141, 42, ..., 15242]
```

@@ -118,3 +128,4 @@

This package behave similarly to `pgrep -P` on \*unix
<img src="https://github.com/simonepri/pidtree/raw/refactor/media/cli.gif" alt="pidtree cli" width="300" align="right"/>
Show a tree of the processes inside your system inside your terminal.

@@ -132,2 +143,9 @@ ```bash

To display the output as a list, similar to the one produced from `pgrep -P $PID`,
pass the `--list` flag.
```bash
npx pidtree --list
```
## API

@@ -137,7 +155,7 @@

## pidtree(pid, [options], [callback]) ⇒ <code>Promise.&lt;Object&gt;</code>
Get the list of child pids of the given pid.
## pidtree(pid, [options], [callback]) ⇒ <code>[Promise.&lt;Array.&lt;Object&gt;&gt;]</code>
Get the list of children pids of the given pid.
**Kind**: global function
**Returns**: <code>Promise.&lt;Object&gt;</code> - Only when the callback is not provided.
**Returns**: <code>Promise.&lt;Array.&lt;Object&gt;&gt;</code> - Only when the callback is not provided.
**Access**: public

@@ -147,9 +165,9 @@

| --- | --- | --- | --- |
| pid | <code>Number</code> \| <code>String</code> | | A pid. |
| pid | <code>Number</code> \| <code>String</code> | | A pid. If -1 will return all the pids. |
| [options] | <code>Object</code> | | Optional options object. |
| [options.root] | <code>Boolean</code> | <code>false</code> | Include the provided pid in the list. |
| [options.root] | <code>Boolean</code> | <code>false</code> | Include the provided pid in the list. Ignored if -1 is passed as pid. |
| [callback] | <code>function</code> | | Called when the list is ready. If not provided a promise is returned instead. |
## Related
## Related
- [pidusage][gh:pidusage] -

@@ -159,2 +177,3 @@ Cross-platform process cpu % and memory usage of a PID

## Authors
- **Simone Primarosa** - [simonepri][github:simonepri]

@@ -165,2 +184,3 @@

## License
This project is licensed under the MIT License - see the [license][license] file for details.

@@ -177,1 +197,2 @@

[gh:ps-tree]: https://github.com/indexzero/ps-tree
[gh:ps-tree-um]: https://github.com/indexzero/ps-tree/issues/30
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc