60 lines
1.4 KiB
JavaScript
60 lines
1.4 KiB
JavaScript
import { promisify } from 'util'
|
|
import { spawn, exec } from 'child_process'
|
|
|
|
const execPromise = promisify(exec)
|
|
|
|
export default function kill(pid, signal) {
|
|
let pids = new Set([pid])
|
|
let getSpawn = null
|
|
|
|
switch (process.platform) {
|
|
case 'win32':
|
|
return execPromise('taskkill /pid ' + pid + ' /T /F').then(() => pids)
|
|
case 'darwin':
|
|
getSpawn = function(parentPid) {
|
|
return spawn('pgrep', ['-P', parentPid])
|
|
}
|
|
break
|
|
default:
|
|
getSpawn = function (parentPid) {
|
|
return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid])
|
|
}
|
|
break
|
|
}
|
|
|
|
return buildTree(pids, getSpawn, pid)
|
|
.then(function() {
|
|
for (let pid of pids) {
|
|
try {
|
|
process.kill(pid, signal)
|
|
} catch (err) {
|
|
if (err.code !== 'ESRCH') throw err;
|
|
}
|
|
}
|
|
return pids
|
|
})
|
|
}
|
|
|
|
function buildTree(allPids, spawnGetChildren, parentPid) {
|
|
allPids.add(parentPid)
|
|
|
|
let ps = spawnGetChildren(parentPid)
|
|
let data = ''
|
|
ps.stdout.on('data', function(buf) {
|
|
data += buf.toString('ascii')
|
|
})
|
|
|
|
return new Promise(function(res) {
|
|
ps.on('close', function(code) {
|
|
// Check if we got error code (usually means empty results)
|
|
if (code !== 0) return res()
|
|
|
|
res(Promise.all(
|
|
data.match(/\d+/g)
|
|
.map(Number)
|
|
.filter(pid => !allPids.has(pid))
|
|
.map(buildTree.bind(this, allPids, spawnGetChildren))
|
|
))
|
|
})
|
|
})
|
|
}
|