From aac38fa190b3897838a327531d0d922665e3340f Mon Sep 17 00:00:00 2001 From: Eugene Pankov Date: Sat, 6 Feb 2021 16:45:38 +0100 Subject: [PATCH] CWD detection on windows where possible --- app/package.json | 3 +- app/yarn.lock | 17 +++-- .../src/services/sessions.service.ts | 67 +++++++------------ terminus-terminal/webpack.config.js | 1 + 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/app/package.json b/app/package.json index 5881f754..45facceb 100644 --- a/app/package.json +++ b/app/package.json @@ -22,7 +22,7 @@ "@angular/platform-browser": "^11.1.1", "@angular/platform-browser-dynamic": "^11.1.1", "@ng-bootstrap/ng-bootstrap": "^6.1.0", - "@terminus-term/node-pty": "0.10.0-beta10", + "@terminus-term/node-pty": "0.10.0-terminus.2", "electron-config": "2.0.0", "electron-debug": "^3.2.0", "electron-is-dev": "1.2.0", @@ -32,6 +32,7 @@ "js-yaml": "4.0.0", "keytar": "^7.2.0", "mz": "^2.7.0", + "native-process-working-directory": "^1.0.2", "ngx-toastr": "^12.0.1", "npm": "6", "path": "0.12.7", diff --git a/app/yarn.lock b/app/yarn.lock index 458f1953..efd3f36b 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -131,10 +131,10 @@ dependencies: debug "^4.1.1" -"@terminus-term/node-pty@0.10.0-beta10": - version "0.10.0-beta10" - resolved "https://registry.yarnpkg.com/@terminus-term/node-pty/-/node-pty-0.10.0-beta10.tgz#de9dade3d7549d44b0906ec0d0b9e1bb411f1f21" - integrity sha512-j9RJk7sD/es4vR6+AR5M/p3SicVxY6kZEeE0UQKhHNcaAla90/mcGeBNicAWPaAkjO1uQZVbYh5cJMMu5unQgA== +"@terminus-term/node-pty@0.10.0-terminus.2": + version "0.10.0-terminus.2" + resolved "https://registry.yarnpkg.com/@terminus-term/node-pty/-/node-pty-0.10.0-terminus.2.tgz#028c7762d13150984bc800b8cd954ceb7dbcac68" + integrity sha512-vcscP3jldTMZeHv0XVxQjwEtnh0usUQgUWvsXtPRMy2rMjijwC1+8xFp/FKPpLpWYNTN8WWmRjSdiw+qGGU4CQ== dependencies: nan "^2.14.0" @@ -2094,6 +2094,13 @@ napi-build-utils@^1.0.1: resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== +native-process-working-directory@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/native-process-working-directory/-/native-process-working-directory-1.0.2.tgz#7843e2fa1490f53cf8d2c7d1913de8b275e8b89a" + integrity sha512-3a67QQV8r3YMUTSOgvtMOCjPDgCpb/8xjv93L8Cqb8bv3hOKsWis4/+8HCu3bgj8ADQV75SCYFSsAGM5G0cXmQ== + dependencies: + node-addon-api "^3.1.0" + ngx-toastr@^12.0.1: version "12.1.0" resolved "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-12.1.0.tgz" @@ -2113,7 +2120,7 @@ node-addon-api@3.0.0: resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz" integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg== -node-addon-api@^3.0.0, node-addon-api@^3.0.2: +node-addon-api@^3.0.0, node-addon-api@^3.0.2, node-addon-api@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz" integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== diff --git a/terminus-terminal/src/services/sessions.service.ts b/terminus-terminal/src/services/sessions.service.ts index 72307842..334ba014 100644 --- a/terminus-terminal/src/services/sessions.service.ts +++ b/terminus-terminal/src/services/sessions.service.ts @@ -2,12 +2,11 @@ import * as psNode from 'ps-node' import * as fs from 'mz/fs' import * as os from 'os' import * as nodePTY from '@terminus-term/node-pty' - +import { getWorkingDirectoryFromPID } from 'native-process-working-directory' import { Observable, Subject } from 'rxjs' import { first } from 'rxjs/operators' import { Injectable } from '@angular/core' import { Logger, LogService, ConfigService, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild } from 'terminus-core' -import { exec } from 'mz/child_process' import { SessionOptions } from '../api/interfaces' /* eslint-disable block-scoped-var */ @@ -20,7 +19,6 @@ try { var windowsProcessTree = require('windows-process-tree') // eslint-disable-line @typescript-eslint/no-var-requires, no-var } catch { } - export interface ChildProcess { pid: number ppid: number @@ -28,7 +26,6 @@ export interface ChildProcess { } const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi -const catalinaDataVolumePrefix = '/System/Volumes/Data' const OSC1337Prefix = Buffer.from('\x1b]1337;') const OSC1337Suffix = Buffer.from('\x07') @@ -97,6 +94,7 @@ export class Session extends BaseSession { private pauseAfterExit = false private guessedCWD: string|null = null private reportedCWD: string + private initialCWD: string|null = null constructor (private config: ConfigService) { super() @@ -154,6 +152,7 @@ export class Session extends BaseSession { this.truePID = processes[0].pid processes = await this.getChildProcesses() } + this.initialCWD = await this.getWorkingDirectory() }, 2000) this.open = true @@ -261,13 +260,7 @@ export class Session extends BaseSession { } supportsWorkingDirectory (): boolean { - if (this.reportedCWD || this.guessedCWD) { - return true - } - if (!this.truePID) { - return false - } - return process.platform !== 'win32' + return !!(this.truePID || this.reportedCWD || this.guessedCWD) } async getWorkingDirectory (): Promise { @@ -277,40 +270,30 @@ export class Session extends BaseSession { if (!this.truePID) { return null } - if (process.platform === 'darwin') { - let lines: string[] = [] - try { - lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n') - } catch (e) { - return null - } - let cwd = lines[lines[1] === 'fcwd' ? 2 : 1].substring(1) - if (cwd.startsWith(catalinaDataVolumePrefix)) { - cwd = cwd.substring(catalinaDataVolumePrefix.length) - } - return cwd + let cwd: string|null = null + try { + cwd = getWorkingDirectoryFromPID(this.truePID) + } catch (exc) { + console.error(exc) } - if (process.platform === 'linux') { - try { - const cwd = await fs.readlink(`/proc/${this.truePID}/cwd`) - return cwd - } catch (exc) { - console.error(exc) - return null - } + + try { + cwd = await fs.realpath(cwd) + } catch {} + + if (process.platform === 'win32' && (cwd === this.initialCWD || cwd === process.env.WINDIR)) { + // shell doesn't truly change its process' CWD + cwd = null } - if (process.platform === 'win32') { - if (!this.guessedCWD) { - return null - } - try { - await fs.access(this.guessedCWD) - } catch (e) { - return null - } - return this.guessedCWD + + cwd = cwd || this.guessedCWD + + try { + await fs.access(cwd) + } catch { + return null } - return null + return cwd } private guessWindowsCWD (data: string) { diff --git a/terminus-terminal/webpack.config.js b/terminus-terminal/webpack.config.js index 53bdd4c2..cc4a34e2 100644 --- a/terminus-terminal/webpack.config.js +++ b/terminus-terminal/webpack.config.js @@ -67,6 +67,7 @@ module.exports = { 'windows-native-registry', '@terminus-term/node-pty', 'windows-process-tree', + 'native-process-working-directory', 'os', /^rxjs/, /^@angular/,