X-Git-Url: https://git.josue.xyz/?p=VSoRC%2F.git;a=blobdiff_plain;f=node_modules%2Fnode-pty%2Fsrc%2FwindowsTerminal.ts;fp=node_modules%2Fnode-pty%2Fsrc%2FwindowsTerminal.ts;h=b0762883fb575423f76604cee88d24d60a50e222;hp=0000000000000000000000000000000000000000;hb=e79e4a5a87f3e84f7c1777f10a954453a69bf540;hpb=4339da12467b75fb8b6ca831f4bf0081c485ed2c diff --git a/node_modules/node-pty/src/windowsTerminal.ts b/node_modules/node-pty/src/windowsTerminal.ts new file mode 100644 index 0000000..b076288 --- /dev/null +++ b/node_modules/node-pty/src/windowsTerminal.ts @@ -0,0 +1,187 @@ +/** + * Copyright (c) 2012-2015, Christopher Jeffrey, Peter Sunde (MIT License) + * Copyright (c) 2016, Daniel Imms (MIT License). + * Copyright (c) 2018, Microsoft Corporation (MIT License). + */ + +import { Socket } from 'net'; +import { Terminal, DEFAULT_COLS, DEFAULT_ROWS } from './terminal'; +import { WindowsPtyAgent } from './windowsPtyAgent'; +import { IPtyOpenOptions, IWindowsPtyForkOptions } from './interfaces'; +import { ArgvOrCommandLine } from './types'; +import { assign } from './utils'; + +const DEFAULT_FILE = 'cmd.exe'; +const DEFAULT_NAME = 'Windows Shell'; + +export class WindowsTerminal extends Terminal { + private _isReady: boolean; + private _deferreds: any[]; + private _agent: WindowsPtyAgent; + + constructor(file?: string, args?: ArgvOrCommandLine, opt?: IWindowsPtyForkOptions) { + super(opt); + + // Initialize arguments + args = args || []; + file = file || DEFAULT_FILE; + opt = opt || {}; + opt.env = opt.env || process.env; + + if (opt.encoding) { + console.warn('Setting encoding on Windows is not supported'); + } + + const env = assign({}, opt.env); + this._cols = opt.cols || DEFAULT_COLS; + this._rows = opt.rows || DEFAULT_ROWS; + const cwd = opt.cwd || process.cwd(); + const name = opt.name || env.TERM || DEFAULT_NAME; + const parsedEnv = this._parseEnv(env); + + // If the terminal is ready + this._isReady = false; + + // Functions that need to run after `ready` event is emitted. + this._deferreds = []; + + // Create new termal. + this._agent = new WindowsPtyAgent(file, args, parsedEnv, cwd, this._cols, this._rows, false, opt.useConpty, opt.conptyInheritCursor); + this._socket = this._agent.outSocket; + + // Not available until `ready` event emitted. + this._pid = this._agent.innerPid; + this._fd = this._agent.fd; + this._pty = this._agent.pty; + + // The forked windows terminal is not available until `ready` event is + // emitted. + this._socket.on('ready_datapipe', () => { + + // These events needs to be forwarded. + ['connect', 'data', 'end', 'timeout', 'drain'].forEach(event => { + this._socket.on(event, () => { + + // Wait until the first data event is fired then we can run deferreds. + if (!this._isReady && event === 'data') { + + // Terminal is now ready and we can avoid having to defer method + // calls. + this._isReady = true; + + // Execute all deferred methods + this._deferreds.forEach(fn => { + // NB! In order to ensure that `this` has all its references + // updated any variable that need to be available in `this` before + // the deferred is run has to be declared above this forEach + // statement. + fn.run(); + }); + + // Reset + this._deferreds = []; + + } + }); + }); + + // Shutdown if `error` event is emitted. + this._socket.on('error', err => { + // Close terminal session. + this._close(); + + // EIO, happens when someone closes our child process: the only process + // in the terminal. + // node < 0.6.14: errno 5 + // node >= 0.6.14: read EIO + if ((err).code) { + if (~(err).code.indexOf('errno 5') || ~(err).code.indexOf('EIO')) return; + } + + // Throw anything else. + if (this.listeners('error').length < 2) { + throw err; + } + }); + + // Cleanup after the socket is closed. + this._socket.on('close', () => { + this.emit('exit', this._agent.exitCode); + this._close(); + }); + + }); + + this._file = file; + this._name = name; + + this._readable = true; + this._writable = true; + + this._forwardEvents(); + } + + protected _write(data: string): void { + this._defer(this._doWrite, data); + } + + private _doWrite(data: string): void { + this._agent.inSocket.write(data); + } + + /** + * openpty + */ + + public static open(options?: IPtyOpenOptions): void { + throw new Error('open() not supported on windows, use Fork() instead.'); + } + + /** + * TTY + */ + + public resize(cols: number, rows: number): void { + if (cols <= 0 || rows <= 0 || isNaN(cols) || isNaN(rows) || cols === Infinity || rows === Infinity) { + throw new Error('resizing must be done using positive cols and rows'); + } + this._defer(() => { + this._agent.resize(cols, rows); + this._cols = cols; + this._rows = rows; + }); + } + + public destroy(): void { + this._defer(() => { + this.kill(); + }); + } + + public kill(signal?: string): void { + this._defer(() => { + if (signal) { + throw new Error('Signals not supported on windows.'); + } + this._close(); + this._agent.kill(); + }); + } + + private _defer(deferredFn: (arg?: A) => void, arg?: A): void { + // If the terminal is ready, execute. + if (this._isReady) { + deferredFn.call(this, arg); + return; + } + + // Queue until terminal is ready. + this._deferreds.push({ + run: () => deferredFn.call(this, arg) + }); + } + + public get process(): string { return this._name; } + public get master(): Socket { throw new Error('master is not supported on Windows'); } + public get slave(): Socket { throw new Error('slave is not supported on Windows'); } +}