From b84d0fc1a307f6103ea2c2620a106db821696434 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 2 Apr 2019 01:11:22 +0800 Subject: Add proper process teminate method --- editors/code/package-lock.json | 51 ++++++++++++++++++++++++++++++ editors/code/package.json | 5 +-- editors/code/src/commands/cargo_watch.ts | 17 ++++++---- editors/code/src/commands/watch_status.ts | 1 - editors/code/src/utils/processes.ts | 40 +++++++++++++++++++++++ editors/code/src/utils/terminateProcess.sh | 12 +++++++ 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 editors/code/src/utils/processes.ts create mode 100644 editors/code/src/utils/terminateProcess.sh diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index 5a0d21e78..008df6f52 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json @@ -607,6 +607,12 @@ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1121,6 +1127,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, "is": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", @@ -1791,6 +1803,15 @@ "util-deprecate": "^1.0.1" } }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, "remove-bom-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", @@ -1902,6 +1923,36 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shx": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.2.tgz", + "integrity": "sha512-aS0mWtW3T2sHAenrSrip2XGv39O9dXIFUqxAEWHEOS1ePtGIBavdPJY1kE2IHl14V/4iCbUiNDPGdyYTtmhSoA==", + "dev": true, + "requires": { + "es6-object-assign": "^1.0.3", + "minimist": "^1.2.0", + "shelljs": "^0.8.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/editors/code/package.json b/editors/code/package.json index 240aff6c9..ba9c9433a 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -18,7 +18,7 @@ "scripts": { "vscode:prepublish": "npm run compile", "package": "vsce package", - "compile": "tsc -p ./", + "compile": "tsc -p ./ && shx cp src/utils/terminateProcess.sh out/utils/terminateProcess.sh", "watch": "tsc -watch -p ./", "postinstall": "node ./node_modules/vscode/bin/install", "fix": "prettier **/*.{json,ts} --write && tslint --project . --fix", @@ -41,7 +41,8 @@ "tslint-config-prettier": "^1.18.0", "typescript": "^3.3.1", "vsce": "^1.57.0", - "vscode": "^1.1.29" + "vscode": "^1.1.29", + "shx": "^0.3.1" }, "activationEvents": [ "onLanguage:rust", diff --git a/editors/code/src/commands/cargo_watch.ts b/editors/code/src/commands/cargo_watch.ts index 037f1e302..e51cac78a 100644 --- a/editors/code/src/commands/cargo_watch.ts +++ b/editors/code/src/commands/cargo_watch.ts @@ -1,9 +1,10 @@ import * as child_process from 'child_process'; import * as path from 'path'; -import * as timers from 'timers'; import * as vscode from 'vscode'; +import { terminate } from '../utils/processes'; import { StatusDisplay } from './watch_status'; + export class CargoWatchProvider { private diagnosticCollection?: vscode.DiagnosticCollection; private cargoProcess?: child_process.ChildProcess; @@ -21,24 +22,25 @@ export class CargoWatchProvider { // Start the cargo watch with json message this.cargoProcess = child_process.spawn( 'cargo', - ['watch', '-x', '"check --message-format json"'], + ['watch', '-x', '\"check --message-format json\"'], { - // stdio: ['ignore', 'pipe', 'ignore'], - shell: true, - cwd: vscode.workspace.rootPath + stdio: ['ignore', 'pipe', 'pipe'], + cwd: vscode.workspace.rootPath, + windowsVerbatimArguments: true, } ); this.cargoProcess.stdout.on('data', (s: string) => { this.processOutput(s); + console.log(s); }); this.cargoProcess.stderr.on('data', (s: string) => { - // console.error('Error on cargo watch : ' + s); + console.error('Error on cargo watch : ' + s); }); this.cargoProcess.on('error', (err: Error) => { - // console.error('Error on spawn cargo process : ' + err); + console.error('Error on spawn cargo process : ' + err); }); } @@ -50,6 +52,7 @@ export class CargoWatchProvider { if (this.cargoProcess) { this.cargoProcess.kill(); + terminate(this.cargoProcess); } } diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts index 1b0611ce3..f027d7bbc 100644 --- a/editors/code/src/commands/watch_status.ts +++ b/editors/code/src/commands/watch_status.ts @@ -1,4 +1,3 @@ -import * as timers from 'timers'; import * as vscode from 'vscode'; const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; diff --git a/editors/code/src/utils/processes.ts b/editors/code/src/utils/processes.ts new file mode 100644 index 000000000..09fdf6e24 --- /dev/null +++ b/editors/code/src/utils/processes.ts @@ -0,0 +1,40 @@ +'use strict'; + +import * as cp from 'child_process'; +import ChildProcess = cp.ChildProcess; + +import { join } from 'path'; + +const isWindows = (process.platform === 'win32'); +const isMacintosh = (process.platform === 'darwin'); +const isLinux = (process.platform === 'linux'); +export function terminate(process: ChildProcess, cwd?: string): boolean { + if (isWindows) { + try { + // This we run in Atom execFileSync is available. + // Ignore stderr since this is otherwise piped to parent.stderr + // which might be already closed. + const options: any = { + stdio: ['pipe', 'pipe', 'ignore'] + }; + if (cwd) { + options.cwd = cwd + } + (cp).execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options); + return true; + } catch (err) { + return false; + } + } else if (isLinux || isMacintosh) { + try { + const cmd = join(__dirname, 'terminateProcess.sh'); + const result = cp.spawnSync(cmd, [process.pid.toString()]); + return result.error ? false : true; + } catch (err) { + return false; + } + } else { + process.kill('SIGKILL'); + return true; + } +} \ No newline at end of file diff --git a/editors/code/src/utils/terminateProcess.sh b/editors/code/src/utils/terminateProcess.sh new file mode 100644 index 000000000..2ec9e1c2e --- /dev/null +++ b/editors/code/src/utils/terminateProcess.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +terminateTree() { + for cpid in $(pgrep -P $1); do + terminateTree $cpid + done + kill -9 $1 > /dev/null 2>&1 +} + +for pid in $*; do + terminateTree $pid +done \ No newline at end of file -- cgit v1.2.3