From 31625788efd83db51fc58a1bc4bc002840f26c29 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Thu, 16 Aug 2018 15:41:53 +0200 Subject: [PATCH 01/15] Updated .gitignore --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 59d842b..4f82b87 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,9 @@ node_modules # Users Environment Variables .lock-wscript + +# WebStorm IDE settings +.idea + +# NPM package lock file +package-lock.json From b18b6d90bd31b3a0cee83b3e9ab179dd8e71c736 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Thu, 16 Aug 2018 16:08:23 +0200 Subject: [PATCH 02/15] Added RSS columns to results --- index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 24e3284..ae47a0d 100755 --- a/index.js +++ b/index.js @@ -42,9 +42,9 @@ module.exports = function childrenOfPid(pid, callback) { 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']); + processLister = spawn('wmic.exe', ['PROCESS', 'GET', 'Name,ProcessId,ParentProcessId,Status,WorkingSetSize']); } else { - processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm']); + processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm,rss']); } es.connect( @@ -63,6 +63,12 @@ module.exports = function childrenOfPid(pid, callback) { return cb(); } + // Convert RSS to number of bytes + columns[4] = parseInt(columns[4], 10); + if (process.platform !== 'win32') { + columns[4] *= 1024; + } + var row = {}; // For each header var h = headers.slice(); @@ -112,6 +118,9 @@ function normalizeHeader(str) { case 'Status': return 'STAT'; break; + case 'WorkingSetSize': + return 'RSS'; + break; default: throw new Error('Unknown process listing header: ' + str); } From abe6f7ae67ebabf8372d1f42f5f89bb32ae60325 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Thu, 16 Aug 2018 16:09:46 +0200 Subject: [PATCH 03/15] Added Node 8 and 10 to Travis tests --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6e3e2a0..cf1b0cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ node_js: - "0.12" - "4.4" - "6.2" + - "8" + - "10" os: - linux - centos From b5c91370b0cc5df9888da5869f9b1e941c546683 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Thu, 16 Aug 2018 20:06:33 +0200 Subject: [PATCH 04/15] Added includeRoot optional argument + unit tests --- index.js | 22 ++++++++++++++++------ test/test.js | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/index.js b/index.js index ae47a0d..328c167 100755 --- a/index.js +++ b/index.js @@ -3,9 +3,15 @@ var spawn = require('child_process').spawn, es = require('event-stream'); -module.exports = function childrenOfPid(pid, callback) { +module.exports = function childrenOfPid(pid, includeRoot, callback) { var headers = null; + // includeRoot is optional parameter + if (typeof includeRoot === 'function') { + callback = includeRoot; + includeRoot = false; + } + if (typeof callback !== 'function') { throw new Error('childrenOfPid(pid, callback) expects callback'); } @@ -79,13 +85,17 @@ module.exports = function childrenOfPid(pid, callback) { return cb(null, row); }), es.writeArray(function (err, ps) { - var parents = [pid], - children = []; + var parents = {}; + var children = []; + + parents[pid] = true; ps.forEach(function (proc) { - if (parents.indexOf(proc.PPID) !== -1) { - parents.push(proc.PID) - children.push(proc) + if (parents[proc.PPID]) { + parents[proc.PID] = true; + children.push(proc); + } else if (includeRoot && pid === proc.PID) { + children.push(proc); } }); diff --git a/test/test.js b/test/test.js index 9e655f2..175a70e 100644 --- a/test/test.js +++ b/test/test.js @@ -49,6 +49,28 @@ test(cyan('FORCE ERROR by calling psTree without supplying a Callback'), functio t.end(); }); +test(cyan('Includes itself it includeRoot is true'), function (t) { + psTree(process.pid, true, function(err, children) { + if (err) { console.log(err); } + t.equal(children.length, 2, green('✓ Two processes found')); + + var current; + var other; + if (children[0].PID === '' + process.pid) { + current = children[0]; + other = children[1]; + } else { + current = children[1]; + other = children[0]; + }; + + t.equal(current.PID, '' + process.pid, green('✓ Current PID is valid')); + t.equal(current.COMM, 'node', green('✓ Current COMM is node')); + t.notEqual(other.PID, '' + process.pid, green('✓ Current PID is valid')); + t.equal(other.COMM, 'ps', green('✓ Current COMM is ps')); + t.end(); + }); +}); test(cyan('Spawn a Child Process and psTree with a String as pid'), function (t) { var child = cp.exec('node ' + scripts.child, function(error, stdout, stderr) {}); From 309ffaf0a77e2b90be9f676b0ebaf93637ea6332 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Fri, 17 Aug 2018 12:36:32 +0200 Subject: [PATCH 05/15] Bugfix: ps on MacOS prints 'COMM' instead of 'COMMAND' --- README.md | 2 +- index.js | 4 ++-- test/test.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e9f1461..20b10a3 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The `ps-tree` module behaves differently on *nix vs. Windows by spawning differe 1. " " need to be striped ```bash -$ ps -A -o comm,ppid,pid,stat +$ ps -A -o command,ppid,pid,stat COMMAND PPID PID STAT bbsd 2899 16958 Ss watch 1914 16964 Z diff --git a/index.js b/index.js index 328c167..670502d 100755 --- a/index.js +++ b/index.js @@ -50,11 +50,11 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { // See also: https://github.com/nodejs/node-v0.x-archive/issues/2318 processLister = spawn('wmic.exe', ['PROCESS', 'GET', 'Name,ProcessId,ParentProcessId,Status,WorkingSetSize']); } else { - processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm,rss']); + processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,command,rss']); } es.connect( - // spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm']).stdout, + // spawn('ps', ['-A', '-o', 'ppid,pid,stat,command']).stdout, processLister.stdout, es.split(), es.map(function (line, cb) { //this could parse alot of unix command output diff --git a/test/test.js b/test/test.js index 175a70e..0ebb5f4 100644 --- a/test/test.js +++ b/test/test.js @@ -65,9 +65,9 @@ test(cyan('Includes itself it includeRoot is true'), function (t) { }; t.equal(current.PID, '' + process.pid, green('✓ Current PID is valid')); - t.equal(current.COMM, 'node', green('✓ Current COMM is node')); + t.equal(current.COMMAND, 'node', green('✓ Current COMM is node')); t.notEqual(other.PID, '' + process.pid, green('✓ Current PID is valid')); - t.equal(other.COMM, 'ps', green('✓ Current COMM is ps')); + t.equal(other.COMMAND, 'ps', green('✓ Current COMM is ps')); t.end(); }); }); From 276f67dc017b3f42fdaed1b3b35e7fe20056e91e Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Fri, 17 Aug 2018 13:34:51 +0200 Subject: [PATCH 06/15] Fixed COMM vs COMMAND problem --- README.md | 2 +- index.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 20b10a3..e9f1461 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The `ps-tree` module behaves differently on *nix vs. Windows by spawning differe 1. " " need to be striped ```bash -$ ps -A -o command,ppid,pid,stat +$ ps -A -o comm,ppid,pid,stat COMMAND PPID PID STAT bbsd 2899 16958 Ss watch 1914 16964 Z diff --git a/index.js b/index.js index 670502d..3f9482a 100755 --- a/index.js +++ b/index.js @@ -50,11 +50,11 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { // See also: https://github.com/nodejs/node-v0.x-archive/issues/2318 processLister = spawn('wmic.exe', ['PROCESS', 'GET', 'Name,ProcessId,ParentProcessId,Status,WorkingSetSize']); } else { - processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,command,rss']); + processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm,rss']); } es.connect( - // spawn('ps', ['-A', '-o', 'ppid,pid,stat,command']).stdout, + // 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 @@ -112,6 +112,8 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { */ function normalizeHeader(str) { if (process.platform !== 'win32') { + // HOTFIX: On Mac ps gives "COMM" instead of "COMMAND" + if (str === "COMM") return "COMMAND"; return str; } From 1ea1c214a5433ef0589f4f667bdc7e998f2eab27 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Fri, 17 Aug 2018 16:06:23 +0200 Subject: [PATCH 07/15] Bumped package.json version, removed CI testing of old Node versions, updated docs --- .travis.yml | 6 ++---- README.md | 2 ++ package.json | 11 +++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index cf1b0cb..c3e9e07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ language: node_js node_js: - - "0.10" - - "0.12" - - "4.4" - - "6.2" - "8" + - "9" - "10" + os: - linux - centos diff --git a/README.md b/README.md index e9f1461..655e6e2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ [![Node.js Version](https://img.shields.io/node/v/ps-tree.svg?style=flat)](http://nodejs.org/download/) [![Dependency Status](https://david-dm.org/indexzero/ps-tree.svg)](https://david-dm.org/indexzero/ps-tree) +NOTE: This is a fork of [ps-tree](https://www.npmjs.com/package/ps-tree) NPM package, with some fixes and extras. + Sometimes you cannot kill child processes like you would expect, this a feature of UNIX. >in UNIX, a process may terminate by using the exit call, and it's parent process may wait for that event by using the wait system call. the wait system call returns the process identifier of a terminated child, so that the parent tell which of the possibly many children has terminated. If the parent terminates, however, all it's children have assigned as their new parent the init process. Thus, the children still have a parent to collect their status and execution statistics. diff --git a/package.json b/package.json index 5380e51..85979d3 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,12 @@ { - "name": "ps-tree", - "version": "1.1.0", + "name": "@apify/ps-tree", + "version": "1.1.1", "description": "Get all children of a pid", "license": "MIT", - "homepage": "http://github.com/indexzero/ps-tree#readme", - "repository": "github:indexzero/ps-tree", + "homepage": "https://github.com/apifytech/ps-tree", + "repository": "https://github.com/apifytech/ps-tree", "bugs": { - "url": "https://github.com/indexzero/ps-tree/issues", - "email": "charlie.robbins@gmail.com" + "url": "https://github.com/apifytech/ps-tree/issues" }, "author": "Charlie Robbins ", "contributors": [ From 858e52d932eb783e9dcb6b577f47b90b74e1ec33 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Thu, 27 Sep 2018 23:30:11 +0200 Subject: [PATCH 08/15] Bugfix: 'error' event from spawn() was ignored --- index.js | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 3f9482a..6225d04 100755 --- a/index.js +++ b/index.js @@ -53,6 +53,8 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm,rss']); } + processLister.on('error', callback); + es.connect( // spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm']).stdout, processLister.stdout, diff --git a/package.json b/package.json index 85979d3..d5629e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apify/ps-tree", - "version": "1.1.1", + "version": "1.1.2", "description": "Get all children of a pid", "license": "MIT", "homepage": "https://github.com/apifytech/ps-tree", From dbcd41be126da6560e1a0a4fb54213226332bf19 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Mon, 26 Nov 2018 19:43:41 +0100 Subject: [PATCH 09/15] Bumped package.json version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d5629e4..6f9901d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apify/ps-tree", - "version": "1.1.2", + "version": "1.1.3", "description": "Get all children of a pid", "license": "MIT", "homepage": "https://github.com/apifytech/ps-tree", @@ -38,7 +38,7 @@ "codeclimate": "cross-env CODECLIMATE_REPO_TOKEN=84436b4f13c70ace9c62e7f04928bf23c234eb212c0232d39d7fb1535beb2da5 codeclimate < coverage/lcov.info" }, "dependencies": { - "event-stream": "~3.3.0" + "event-stream": "3.3.4" }, "devDependencies": { "chalk": "^1.0.0", From 5b76de2ae98192ab609a7070a19f01eb63b3ab49 Mon Sep 17 00:00:00 2001 From: polikeiji Date: Mon, 3 May 2021 13:00:48 +0900 Subject: [PATCH 10/15] [fix] Fix that RSS is never returned on Windows --- index.js | 15 ++++++++------- test/test.js | 9 +++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 6225d04..4c0316e 100755 --- a/index.js +++ b/index.js @@ -72,8 +72,14 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { } // Convert RSS to number of bytes - columns[4] = parseInt(columns[4], 10); - if (process.platform !== 'win32') { + if (process.platform == 'win32') { + // For Windows, WMIC.exe never returns any value for "Status" and it causes "WorkingSetSize" is set at columns[3]. + // See: https://docs.microsoft.com/ja-jp/windows/win32/cimwin32prov/win32-process?redirectedfrom=MSDN + columns[4] = parseInt(columns[3], 10); + columns[3] = null; + } + else { + columns[4] = parseInt(columns[4], 10); columns[4] *= 1024; } @@ -122,19 +128,14 @@ function normalizeHeader(str) { switch (str) { case 'Name': return 'COMMAND'; - break; case 'ParentProcessId': return 'PPID'; - break; case 'ProcessId': return 'PID'; - break; case 'Status': return 'STAT'; - break; case 'WorkingSetSize': return 'RSS'; - break; default: throw new Error('Unknown process listing header: ' + str); } diff --git a/test/test.js b/test/test.js index 0ebb5f4..30b5e4c 100644 --- a/test/test.js +++ b/test/test.js @@ -9,6 +9,9 @@ var red = chalk.red, green = chalk.green, cyan = chalk.cyan; +var isWin = process.platform === 'win32'; +var isNumGreaterThanZero = (n) => !isNaN(parseInt(n, 10)) && n > 0; + var scripts = { parent: path.join(__dirname, 'exec', 'parent.js'), child: path.join(__dirname, 'exec', 'child.js') @@ -65,9 +68,11 @@ test(cyan('Includes itself it includeRoot is true'), function (t) { }; t.equal(current.PID, '' + process.pid, green('✓ Current PID is valid')); - t.equal(current.COMMAND, 'node', green('✓ Current COMM is node')); + t.equal(current.COMMAND, isWin ? 'node.exe' : 'node', green('✓ Current COMM is node')); + t.equal(isNumGreaterThanZero(current.RSS), true, green('✓ Current RSS is valid')); t.notEqual(other.PID, '' + process.pid, green('✓ Current PID is valid')); - t.equal(other.COMMAND, 'ps', green('✓ Current COMM is ps')); + t.equal(other.COMMAND, isWin ? 'WMIC.exe' : 'ps', green('✓ Current COMM is ps')); + t.equal(isNumGreaterThanZero(other.RSS), true, green('✓ Other RSS is valid')); t.end(); }); }); From ccfeeb72f6cdba81136998aabab28bbabb1fc133 Mon Sep 17 00:00:00 2001 From: polikeiji Date: Mon, 3 May 2021 15:18:19 +0900 Subject: [PATCH 11/15] [fix] Fix that RSS is never returned on Windows --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 4c0316e..a530871 100755 --- a/index.js +++ b/index.js @@ -73,7 +73,7 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { // Convert RSS to number of bytes if (process.platform == 'win32') { - // For Windows, WMIC.exe never returns any value for "Status" and it causes "WorkingSetSize" is set at columns[3]. + // For Windows, WMIC.exe never returns any value for "Status" and it causes "WorkingSetSize" is set at columns[3] // See: https://docs.microsoft.com/ja-jp/windows/win32/cimwin32prov/win32-process?redirectedfrom=MSDN columns[4] = parseInt(columns[3], 10); columns[3] = null; From 7046081f836bf40ba491d7ae676c8c44d6b988b9 Mon Sep 17 00:00:00 2001 From: polikeiji Date: Mon, 3 May 2021 23:52:26 +0900 Subject: [PATCH 12/15] [refactor] Omitted 'Status' in the WMIC call --- index.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index a530871..aeed808 100755 --- a/index.js +++ b/index.js @@ -48,7 +48,7 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { 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,WorkingSetSize']); + processLister = spawn('wmic.exe', ['PROCESS', 'GET', 'Name,ProcessId,ParentProcessId,WorkingSetSize']); } else { processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm,rss']); } @@ -73,10 +73,7 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { // Convert RSS to number of bytes if (process.platform == 'win32') { - // For Windows, WMIC.exe never returns any value for "Status" and it causes "WorkingSetSize" is set at columns[3] - // See: https://docs.microsoft.com/ja-jp/windows/win32/cimwin32prov/win32-process?redirectedfrom=MSDN - columns[4] = parseInt(columns[3], 10); - columns[3] = null; + columns[3] = parseInt(columns[3], 10); } else { columns[4] = parseInt(columns[4], 10); @@ -90,6 +87,13 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { row[h.shift()] = h.length ? columns.shift() : columns.join(' '); } + // For Windows, WMIC.exe never returns any value for "Status" which used to get value corresponding to "STAT" + // See: https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-process?redirectedfrom=MSDN + // So just set "null" for the backward compatibility. + if (process.platform == 'win32') { + row['STAT'] = null; + } + return cb(null, row); }), es.writeArray(function (err, ps) { From 639295135cc82257fc6e18dc92a57bd9b12d7246 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Tue, 4 May 2021 13:50:48 +0200 Subject: [PATCH 13/15] Bumped package.json version to 1.1.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6f9901d..b34b024 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apify/ps-tree", - "version": "1.1.3", + "version": "1.1.4", "description": "Get all children of a pid", "license": "MIT", "homepage": "https://github.com/apifytech/ps-tree", From 6324e5a8b0a7d91f369e9d8129e12341d2bdda30 Mon Sep 17 00:00:00 2001 From: Satvik Choudhary Date: Tue, 21 Feb 2023 19:33:01 +0530 Subject: [PATCH 14/15] move process name to be the last argument --- index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index aeed808..3579000 100755 --- a/index.js +++ b/index.js @@ -48,9 +48,9 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { 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,WorkingSetSize']); + processLister = spawn('wmic.exe', ['PROCESS', 'GET', 'ProcessId,ParentProcessId,WorkingSetSize,Name']); } else { - processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,comm,rss']); + processLister = spawn('ps', ['-A', '-o', 'ppid,pid,stat,rss,comm']); } processLister.on('error', callback); @@ -73,11 +73,11 @@ module.exports = function childrenOfPid(pid, includeRoot, callback) { // Convert RSS to number of bytes if (process.platform == 'win32') { - columns[3] = parseInt(columns[3], 10); + columns[2] = parseInt(columns[2], 10); } else { - columns[4] = parseInt(columns[4], 10); - columns[4] *= 1024; + columns[3] = parseInt(columns[3], 10); + columns[3] *= 1024; } var row = {}; From 3d60bc582876d2bbf928b8cfcc49b9d8c68b3616 Mon Sep 17 00:00:00 2001 From: Jan Curn Date: Wed, 1 Mar 2023 22:08:50 +0100 Subject: [PATCH 15/15] Bumped version from 1.1.4 to 1.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b34b024..bbccfc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apify/ps-tree", - "version": "1.1.4", + "version": "1.2.0", "description": "Get all children of a pid", "license": "MIT", "homepage": "https://github.com/apifytech/ps-tree",