X-Git-Url: https://git.josue.xyz/?p=VSoRC%2F.git;a=blobdiff_plain;f=node_modules%2Fnode-pty%2Flib%2FwindowsPtyAgent.js;fp=node_modules%2Fnode-pty%2Flib%2FwindowsPtyAgent.js;h=4ef3fd678c3f84a37e663f92208b2631d50032cd;hp=0000000000000000000000000000000000000000;hb=e79e4a5a87f3e84f7c1777f10a954453a69bf540;hpb=4339da12467b75fb8b6ca831f4bf0081c485ed2c diff --git a/node_modules/node-pty/lib/windowsPtyAgent.js b/node_modules/node-pty/lib/windowsPtyAgent.js new file mode 100644 index 0000000..4ef3fd6 --- /dev/null +++ b/node_modules/node-pty/lib/windowsPtyAgent.js @@ -0,0 +1,310 @@ +"use strict"; +/** + * Copyright (c) 2012-2015, Christopher Jeffrey, Peter Sunde (MIT License) + * Copyright (c) 2016, Daniel Imms (MIT License). + * Copyright (c) 2018, Microsoft Corporation (MIT License). + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var os = require("os"); +var path = require("path"); +var net_1 = require("net"); +var child_process_1 = require("child_process"); +var conptyNative; +var winptyNative; +/** + * The amount of time to wait for additional data after the conpty shell process has exited before + * shutting down the socket. The timer will be reset if a new data event comes in after the timer + * has started. + */ +var FLUSH_DATA_INTERVAL = 20; +/** + * This agent sits between the WindowsTerminal class and provides a common interface for both conpty + * and winpty. + */ +var WindowsPtyAgent = /** @class */ (function () { + function WindowsPtyAgent(file, args, env, cwd, cols, rows, debug, _useConpty, conptyInheritCursor) { + var _this = this; + if (conptyInheritCursor === void 0) { conptyInheritCursor = false; } + this._useConpty = _useConpty; + if (this._useConpty === undefined || this._useConpty === true) { + this._useConpty = this._getWindowsBuildNumber() >= 18309; + } + if (this._useConpty) { + if (!conptyNative) { + try { + conptyNative = require('../build/Release/conpty.node'); + } + catch (outerError) { + try { + conptyNative = require('../build/Debug/conpty.node'); + } + catch (innerError) { + console.error('innerError', innerError); + // Re-throw the exception from the Release require if the Debug require fails as well + throw outerError; + } + } + } + } + else { + if (!winptyNative) { + try { + winptyNative = require('../build/Release/pty.node'); + } + catch (outerError) { + try { + winptyNative = require('../build/Debug/pty.node'); + } + catch (innerError) { + console.error('innerError', innerError); + // Re-throw the exception from the Release require if the Debug require fails as well + throw outerError; + } + } + } + } + this._ptyNative = this._useConpty ? conptyNative : winptyNative; + // Sanitize input variable. + cwd = path.resolve(cwd); + // Compose command line + var commandLine = argsToCommandLine(file, args); + // Open pty session. + var term; + if (this._useConpty) { + term = this._ptyNative.startProcess(file, cols, rows, debug, this._generatePipeName(), conptyInheritCursor); + } + else { + term = this._ptyNative.startProcess(file, commandLine, env, cwd, cols, rows, debug); + this._pid = term.pid; + this._innerPid = term.innerPid; + this._innerPidHandle = term.innerPidHandle; + } + // Not available on windows. + this._fd = term.fd; + // Generated incremental number that has no real purpose besides using it + // as a terminal id. + this._pty = term.pty; + // Create terminal pipe IPC channel and forward to a local unix socket. + this._outSocket = new net_1.Socket(); + this._outSocket.setEncoding('utf8'); + this._outSocket.connect(term.conout, function () { + // TODO: Emit event on agent instead of socket? + // Emit ready event. + _this._outSocket.emit('ready_datapipe'); + }); + this._inSocket = new net_1.Socket(); + this._inSocket.setEncoding('utf8'); + this._inSocket.connect(term.conin); + // TODO: Wait for ready event? + if (this._useConpty) { + var connect = this._ptyNative.connect(this._pty, commandLine, cwd, env, function (c) { return _this._$onProcessExit(c); }); + this._innerPid = connect.pid; + } + } + Object.defineProperty(WindowsPtyAgent.prototype, "inSocket", { + get: function () { return this._inSocket; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(WindowsPtyAgent.prototype, "outSocket", { + get: function () { return this._outSocket; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(WindowsPtyAgent.prototype, "fd", { + get: function () { return this._fd; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(WindowsPtyAgent.prototype, "innerPid", { + get: function () { return this._innerPid; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(WindowsPtyAgent.prototype, "pty", { + get: function () { return this._pty; }, + enumerable: true, + configurable: true + }); + WindowsPtyAgent.prototype.resize = function (cols, rows) { + if (this._useConpty) { + if (this._exitCode !== undefined) { + throw new Error('Cannot resize a pty that has already exited'); + } + this._ptyNative.resize(this._pty, cols, rows); + return; + } + this._ptyNative.resize(this._pid, cols, rows); + }; + WindowsPtyAgent.prototype.kill = function () { + var _this = this; + this._inSocket.readable = false; + this._inSocket.writable = false; + this._outSocket.readable = false; + this._outSocket.writable = false; + // Tell the agent to kill the pty, this releases handles to the process + if (this._useConpty) { + this._getConsoleProcessList().then(function (consoleProcessList) { + consoleProcessList.forEach(function (pid) { + try { + process.kill(pid); + } + catch (e) { + // Ignore if process cannot be found (kill ESRCH error) + } + }); + _this._ptyNative.kill(_this._pty); + }); + } + else { + this._ptyNative.kill(this._pid, this._innerPidHandle); + // Since pty.kill closes the handle it will kill most processes by itself + // and process IDs can be reused as soon as all handles to them are + // dropped, we want to immediately kill the entire console process list. + // If we do not force kill all processes here, node servers in particular + // seem to become detached and remain running (see + // Microsoft/vscode#26807). + var processList = this._ptyNative.getProcessList(this._pid); + processList.forEach(function (pid) { + try { + process.kill(pid); + } + catch (e) { + // Ignore if process cannot be found (kill ESRCH error) + } + }); + } + }; + WindowsPtyAgent.prototype._getConsoleProcessList = function () { + var _this = this; + return new Promise(function (resolve) { + var agent = child_process_1.fork(path.join(__dirname, 'conpty_console_list_agent'), [_this._innerPid.toString()]); + agent.on('message', function (message) { + clearTimeout(timeout); + resolve(message.consoleProcessList); + }); + var timeout = setTimeout(function () { + // Something went wrong, just send back the shell PID + agent.kill(); + resolve([_this._innerPid]); + }, 5000); + }); + }; + Object.defineProperty(WindowsPtyAgent.prototype, "exitCode", { + get: function () { + if (this._useConpty) { + return this._exitCode; + } + return this._ptyNative.getExitCode(this._innerPidHandle); + }, + enumerable: true, + configurable: true + }); + WindowsPtyAgent.prototype._getWindowsBuildNumber = function () { + var osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release()); + var buildNumber = 0; + if (osVersion && osVersion.length === 4) { + buildNumber = parseInt(osVersion[3]); + } + return buildNumber; + }; + WindowsPtyAgent.prototype._generatePipeName = function () { + return "conpty-" + Math.random() * 10000000; + }; + /** + * Triggered from the native side when a contpy process exits. + */ + WindowsPtyAgent.prototype._$onProcessExit = function (exitCode) { + var _this = this; + this._exitCode = exitCode; + this._flushDataAndCleanUp(); + this._outSocket.on('data', function () { return _this._flushDataAndCleanUp(); }); + }; + WindowsPtyAgent.prototype._flushDataAndCleanUp = function () { + var _this = this; + if (this._closeTimeout) { + clearTimeout(this._closeTimeout); + } + this._closeTimeout = setTimeout(function () { return _this._cleanUpProcess(); }, FLUSH_DATA_INTERVAL); + }; + WindowsPtyAgent.prototype._cleanUpProcess = function () { + this._inSocket.readable = false; + this._inSocket.writable = false; + this._outSocket.readable = false; + this._outSocket.writable = false; + this._outSocket.destroy(); + }; + return WindowsPtyAgent; +}()); +exports.WindowsPtyAgent = WindowsPtyAgent; +// Convert argc/argv into a Win32 command-line following the escaping convention +// documented on MSDN (e.g. see CommandLineToArgvW documentation). Copied from +// winpty project. +function argsToCommandLine(file, args) { + if (isCommandLine(args)) { + if (args.length === 0) { + return file; + } + return argsToCommandLine(file, []) + " " + args; + } + var argv = [file]; + Array.prototype.push.apply(argv, args); + var result = ''; + for (var argIndex = 0; argIndex < argv.length; argIndex++) { + if (argIndex > 0) { + result += ' '; + } + var arg = argv[argIndex]; + // if it is empty or it contains whitespace and is not already quoted + var hasLopsidedEnclosingQuote = xOr((arg[0] !== '"'), (arg[arg.length - 1] !== '"')); + var hasNoEnclosingQuotes = ((arg[0] !== '"') && (arg[arg.length - 1] !== '"')); + var quote = arg === '' || + (arg.indexOf(' ') !== -1 || + arg.indexOf('\t') !== -1) && + ((arg.length > 1) && + (hasLopsidedEnclosingQuote || hasNoEnclosingQuotes)); + if (quote) { + result += '\"'; + } + var bsCount = 0; + for (var i = 0; i < arg.length; i++) { + var p = arg[i]; + if (p === '\\') { + bsCount++; + } + else if (p === '"') { + result += repeatText('\\', bsCount * 2 + 1); + result += '"'; + bsCount = 0; + } + else { + result += repeatText('\\', bsCount); + bsCount = 0; + result += p; + } + } + if (quote) { + result += repeatText('\\', bsCount * 2); + result += '\"'; + } + else { + result += repeatText('\\', bsCount); + } + } + return result; +} +exports.argsToCommandLine = argsToCommandLine; +function isCommandLine(args) { + return typeof args === 'string'; +} +function repeatText(text, count) { + var result = ''; + for (var i = 0; i < count; i++) { + result += text; + } + return result; +} +function xOr(arg1, arg2) { + return ((arg1 && !arg2) || (!arg1 && arg2)); +} +//# sourceMappingURL=windowsPtyAgent.js.map \ No newline at end of file