From d181cccb66b9946fef66e5e178530acb44cce829 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Sat, 19 May 2018 17:04:12 -0700 Subject: [PATCH 1/2] Switch to named pipes --- src/debugAdapter.ts | 7 ++++--- src/session.ts | 27 ++++++++++++++++----------- src/utils.ts | 14 +++++--------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/debugAdapter.ts b/src/debugAdapter.ts index 3886c30904..838def40bf 100644 --- a/src/debugAdapter.ts +++ b/src/debugAdapter.ts @@ -4,6 +4,7 @@ import fs = require("fs"); import net = require("net"); +import os = require("os"); import path = require("path"); import { Logger } from "./logging"; import utils = require("./utils"); @@ -39,10 +40,10 @@ function startDebugging() { utils.deleteSessionFile(debugSessionFilePath); // Establish connection before setting up the session - debugAdapterLogWriter.write("Connecting to port: " + sessionDetails.debugServicePort + "\r\n"); + debugAdapterLogWriter.write("Connecting to pipe: " + sessionDetails.debugServicePipeName + "\r\n"); let isConnected = false; - const debugServiceSocket = net.connect(sessionDetails.debugServicePort, "127.0.0.1"); + const debugServiceSocket = net.connect(utils.getPipePath(sessionDetails.debugServicePipeName)); // Write any errors to the log file debugServiceSocket.on( @@ -73,7 +74,7 @@ function startDebugging() { // Resume the stdin stream process.stdin.resume(); - }); + }); // When the socket closes, end the session debugServiceSocket.on( diff --git a/src/session.ts b/src/session.ts index 44073e17a7..414f92258b 100644 --- a/src/session.ts +++ b/src/session.ts @@ -3,6 +3,7 @@ *--------------------------------------------------------*/ import cp = require("child_process"); +import crypto = require("crypto"); import fs = require("fs"); import net = require("net"); import os = require("os"); @@ -165,19 +166,23 @@ export class SessionManager implements Middleware { } } + // Generate a random id for the named pipes in case they have multiple instances of PSES running + const id = crypto.randomBytes(10).toString("hex"); this.editorServicesArgs = - "-HostName 'Visual Studio Code Host' " + - "-HostProfileId 'Microsoft.VSCode' " + - "-HostVersion '" + this.hostVersion + "' " + - "-AdditionalModules @('PowerShellEditorServices.VSCode') " + - "-BundledModulesPath '" + this.bundledModulesPath + "' " + - "-EnableConsoleRepl "; + `-HostName 'Visual Studio Code Host' ` + + `-HostProfileId 'Microsoft.VSCode' ` + + `-HostVersion '${this.hostVersion}'` + + `-AdditionalModules @('PowerShellEditorServices.VSCode') ` + + `-BundledModulesPath '${this.bundledModulesPath}'` + + `-EnableConsoleRepl ` + + `-LanguageServicePipeName LanguageService_${id}.pipe ` + + `-DebugServicePipeName DebugService_${id}.pipe `; if (this.sessionSettings.developer.editorServicesWaitForDebugger) { - this.editorServicesArgs += "-WaitForDebugger "; + this.editorServicesArgs += `-WaitForDebugger `; } if (this.sessionSettings.developer.editorServicesLogLevel) { - this.editorServicesArgs += "-LogLevel '" + this.sessionSettings.developer.editorServicesLogLevel + "' "; + this.editorServicesArgs += `-LogLevel '${this.sessionSettings.developer.editorServicesLogLevel}' `; } this.startPowerShell(); @@ -531,18 +536,18 @@ export class SessionManager implements Middleware { private startLanguageClient(sessionDetails: utils.IEditorServicesSessionDetails) { - const port = sessionDetails.languageServicePort; + const pipeName = sessionDetails.languageServicePipeName; // Log the session details object this.log.write(JSON.stringify(sessionDetails)); try { - this.log.write("Connecting to language service on port " + port + "..."); + this.log.write("Connecting to language service on pipe " + pipeName + "..."); const connectFunc = () => { return new Promise( (resolve, reject) => { - const socket = net.connect(port); + const socket = net.connect(utils.getPipePath(pipeName)); socket.on( "connect", () => { diff --git a/src/utils.ts b/src/utils.ts index 65ec4332bc..660320807f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -26,15 +26,9 @@ export function getPipePath(pipeName: string) { if (os.platform() === "win32") { return "\\\\.\\pipe\\" + pipeName; } else { - // On UNIX platforms the pipe will live under the temp path - // For details on how this path is computed, see the corefx - // source for System.IO.Pipes.PipeStream: - // tslint:disable-next-line:max-line-length - // https://github.com/dotnet/corefx/blob/d0dc5fc099946adc1035b34a8b1f6042eddb0c75/src/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs#L340 - return path.resolve( - os.tmpdir(), - ".dotnet", "corefx", "pipe", - pipeName); + // Windows uses NamedPipes where non-Windows platforms use Unix Domain Sockets. + // This requires connecting to the pipe file in different locations on Windows vs non-Windows. + return path.join(os.tmpdir(), `CoreFxPipe_${pipeName}`); } } @@ -46,6 +40,8 @@ export interface IEditorServicesSessionDetails { channel: string; languageServicePort: number; debugServicePort: number; + languageServicePipeName: string; + debugServicePipeName: string; } export type IReadSessionFileCallback = (details: IEditorServicesSessionDetails) => void; From 790dbd5bfea2d062603250354f02b3964685b1d2 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Mon, 21 May 2018 15:04:41 -0700 Subject: [PATCH 2/2] no need for string interpolation --- src/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/session.ts b/src/session.ts index 414f92258b..97d07c1767 100644 --- a/src/session.ts +++ b/src/session.ts @@ -179,7 +179,7 @@ export class SessionManager implements Middleware { `-DebugServicePipeName DebugService_${id}.pipe `; if (this.sessionSettings.developer.editorServicesWaitForDebugger) { - this.editorServicesArgs += `-WaitForDebugger `; + this.editorServicesArgs += "-WaitForDebugger "; } if (this.sessionSettings.developer.editorServicesLogLevel) { this.editorServicesArgs += `-LogLevel '${this.sessionSettings.developer.editorServicesLogLevel}' `;