mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 01:00:29 -04:00
Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)
* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 * disable strict null check
This commit is contained in:
@@ -11,9 +11,12 @@ import * as fs from 'fs';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IShellLaunchConfig, ITerminalChildProcess, SHELL_PATH_INVALID_EXIT_CODE, SHELL_PATH_DIRECTORY_EXIT_CODE, SHELL_CWD_INVALID_EXIT_CODE } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { exec } from 'child_process';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { stat } from 'vs/base/node/pfs';
|
||||
import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
private _exitCode: number;
|
||||
@@ -29,8 +32,8 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
public get onProcessData(): Event<string> { return this._onProcessData.event; }
|
||||
private readonly _onProcessExit = new Emitter<number>();
|
||||
public get onProcessExit(): Event<number> { return this._onProcessExit.event; }
|
||||
private readonly _onProcessIdReady = new Emitter<number>();
|
||||
public get onProcessIdReady(): Event<number> { return this._onProcessIdReady.event; }
|
||||
private readonly _onProcessReady = new Emitter<{ pid: number, cwd: string }>();
|
||||
public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; }
|
||||
private readonly _onProcessTitleChanged = new Emitter<string>();
|
||||
public get onProcessTitleChanged(): Event<string> { return this._onProcessTitleChanged.event; }
|
||||
|
||||
@@ -54,14 +57,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
|
||||
this._initialCwd = cwd;
|
||||
|
||||
// Only use ConPTY when the client is non WoW64 (see #72190) and the Windows build number is at least 18309 (for
|
||||
// stability/performance reasons)
|
||||
const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
|
||||
const useConpty = windowsEnableConpty &&
|
||||
process.platform === 'win32' &&
|
||||
!is32ProcessOn64Windows &&
|
||||
getWindowsBuildNumber() >= 18309;
|
||||
|
||||
const useConpty = windowsEnableConpty && process.platform === 'win32' && getWindowsBuildNumber() >= 18309;
|
||||
const options: pty.IPtyForkOptions | pty.IWindowsPtyForkOptions = {
|
||||
name: shellName,
|
||||
cwd,
|
||||
@@ -72,16 +68,43 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
conptyInheritCursor: true
|
||||
};
|
||||
|
||||
// TODO: Need to verify whether executable is on $PATH, otherwise things like cmd.exe will break
|
||||
// fs.stat(shellLaunchConfig.executable!, (err) => {
|
||||
// if (err && err.code === 'ENOENT') {
|
||||
// this._exitCode = SHELL_PATH_INVALID_EXIT_CODE;
|
||||
// this._queueProcessExit();
|
||||
// this._processStartupComplete = Promise.resolve(undefined);
|
||||
// return;
|
||||
// }
|
||||
this.setupPtyProcess(shellLaunchConfig, options);
|
||||
// });
|
||||
const cwdVerification = stat(cwd).then(async stat => {
|
||||
if (!stat.isDirectory()) {
|
||||
return Promise.reject(SHELL_CWD_INVALID_EXIT_CODE);
|
||||
}
|
||||
}, async err => {
|
||||
if (err && err.code === 'ENOENT') {
|
||||
// So we can include in the error message the specified CWD
|
||||
shellLaunchConfig.cwd = cwd;
|
||||
return Promise.reject(SHELL_CWD_INVALID_EXIT_CODE);
|
||||
}
|
||||
});
|
||||
|
||||
const exectuableVerification = stat(shellLaunchConfig.executable!).then(async stat => {
|
||||
if (!stat.isFile() && !stat.isSymbolicLink()) {
|
||||
return Promise.reject(stat.isDirectory() ? SHELL_PATH_DIRECTORY_EXIT_CODE : SHELL_PATH_INVALID_EXIT_CODE);
|
||||
}
|
||||
}, async (err) => {
|
||||
if (err && err.code === 'ENOENT') {
|
||||
let cwd = shellLaunchConfig.cwd instanceof URI ? shellLaunchConfig.cwd.path : shellLaunchConfig.cwd!;
|
||||
const executable = await findExecutable(shellLaunchConfig.executable!, cwd);
|
||||
if (!executable) {
|
||||
return Promise.reject(SHELL_PATH_INVALID_EXIT_CODE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Promise.all([cwdVerification, exectuableVerification]).then(() => {
|
||||
this.setupPtyProcess(shellLaunchConfig, options);
|
||||
}).catch((exitCode: number) => {
|
||||
return this._launchFailed(exitCode);
|
||||
});
|
||||
}
|
||||
|
||||
private _launchFailed(exitCode: number): void {
|
||||
this._exitCode = exitCode;
|
||||
this._queueProcessExit();
|
||||
this._processStartupComplete = Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
private setupPtyProcess(shellLaunchConfig: IShellLaunchConfig, options: pty.IPtyForkOptions): void {
|
||||
@@ -90,7 +113,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
const ptyProcess = pty.spawn(shellLaunchConfig.executable!, args, options);
|
||||
this._ptyProcess = ptyProcess;
|
||||
this._processStartupComplete = new Promise<void>(c => {
|
||||
this.onProcessIdReady(() => c());
|
||||
this.onProcessReady(() => c());
|
||||
});
|
||||
ptyProcess.on('data', data => {
|
||||
this._onProcessData.fire(data);
|
||||
@@ -118,7 +141,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
this._titleInterval = null;
|
||||
this._onProcessData.dispose();
|
||||
this._onProcessExit.dispose();
|
||||
this._onProcessIdReady.dispose();
|
||||
this._onProcessReady.dispose();
|
||||
this._onProcessTitleChanged.dispose();
|
||||
}
|
||||
|
||||
@@ -169,7 +192,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
}
|
||||
|
||||
private _sendProcessId(ptyProcess: pty.IPty) {
|
||||
this._onProcessIdReady.fire(ptyProcess.pid);
|
||||
this._onProcessReady.fire({ pid: ptyProcess.pid, cwd: this._initialCwd });
|
||||
}
|
||||
|
||||
private _sendProcessTitle(ptyProcess: pty.IPty): void {
|
||||
@@ -200,6 +223,9 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
if (typeof cols !== 'number' || typeof rows !== 'number' || isNaN(cols) || isNaN(rows)) {
|
||||
return;
|
||||
}
|
||||
// Ensure that cols and rows are always >= 1, this prevents a native
|
||||
// exception in winpty.
|
||||
if (this._ptyProcess) {
|
||||
|
||||
Reference in New Issue
Block a user