Skip to content

Commit

Permalink
fix: if no ps, walk /proc to kill child fully
Browse files Browse the repository at this point in the history
Originally used ps-tree which relied on `ps` on *nix. But if the system
didn't have `ps` at all, we'd try to kill the child process, but alas
this would not always work, as we're spawning `sh` and _then_ node, so
the kill would only kill the `sh` process, and not the running node
process.

The new @remy/pstree lib sniffs for `ps` and defers to ps-tree,
otherwise it will walk /proc and map the PPID to the child process
allowing nodemon to fully clean up.
  • Loading branch information
remy committed Dec 15, 2017
1 parent 10ded94 commit bf9b7a6
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 33 deletions.
38 changes: 12 additions & 26 deletions lib/monitor/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,9 @@ var child = null; // the actual child process we spawn
var killedAfterChange = false;
var noop = function () { };
var restart = null;
var psTree = require('ps-tree');
var hasPS = true;
var psTree = require('@remy/pstree');
var path = require('path');

// discover if the OS has `ps`, and therefore can use psTree
exec('ps', function (error) {
if (error) {
hasPS = false;
}
});

function run(options) {
var cmd = config.command.raw;

Expand Down Expand Up @@ -291,23 +283,17 @@ function kill(child, signal, callback) {
exec('taskkill /pid ' + child.pid + ' /T /F');
callback();
} else {
if (hasPS) {
// we use psTree to kill the full subtree of nodemon, because when
// spawning processes like `coffee` under the `--debug` flag, it'll spawn
// it's own child, and that can't be killed by nodemon, so psTree gives us
// an array of PIDs that have spawned under nodemon, and we send each the
// configured signal (defaul: SIGUSR2) signal, which fixes #335
psTree(child.pid, function (err, kids) {
spawn('kill', ['-s', signal, child.pid].concat(kids.map(function (p) {
return p.PID;
}))).on('close', callback);
});
} else {
exec('kill -s ' + signal + ' ' + child.pid, function () {
// ignore if the process has been killed already
callback();
});
}
// we use psTree to kill the full subtree of nodemon, because when
// spawning processes like `coffee` under the `--debug` flag, it'll spawn
// it's own child, and that can't be killed by nodemon, so psTree gives us
// an array of PIDs that have spawned under nodemon, and we send each the
// configured signal (default: SIGUSR2) signal, which fixes #335
// note that psTree also works if `ps` is missing by looking in /proc
psTree(child.pid, function (err, kids) {
spawn('kill', ['-s', signal, child.pid].concat(kids.map(function (p) {
return p.PID;
}))).on('close', callback);
});
}
}

Expand Down
20 changes: 14 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@
"should": "~4.0.0"
},
"dependencies": {
"@remy/pstree": "^1.0.0",
"chokidar": "^1.7.0",
"debug": "^2.6.8",
"es6-promise": "^3.3.1",
"ignore-by-default": "^1.0.1",
"lodash.defaults": "^3.1.2",
"minimatch": "^3.0.4",
"ps-tree": "^1.1.0",
"touch": "^3.1.0",
"undefsafe": "0.0.3",
"update-notifier": "^2.3.0"
Expand Down

0 comments on commit bf9b7a6

Please sign in to comment.