/**
 * Copyright (c) 2012-2015, Christopher Jeffrey (MIT License)
 * Copyright (c) 2016, Daniel Imms (MIT License).
 * Copyright (c) 2018, Microsoft Corporation (MIT License).
 */ import * as path from 'path' ; import { Socket } from 'net' ; import { EventEmitter } from 'events' ; import { ITerminal , IPtyForkOptions } from './interfaces' ; export const DEFAULT_COLS = 80 ; export const DEFAULT_ROWS = 24 ; export abstract class Terminal implements ITerminal { protected _socket : Socket ; protected _pid : number ; protected _fd : number ; protected _pty : any ; protected _file : string ; protected _name : string ; protected _cols : number ; protected _rows : number ; protected _readable : boolean ; protected _writable : boolean ; protected _internalee : EventEmitter ; public get pid ( ) : number { return this . _pid ; } constructor ( opt ? ) { this . _internalee = new EventEmitter ( ) ; if ( ! opt ) { return ; } this . _checkType ( 'name' , opt . name ? opt . name : null , 'string' ) ; this . _checkType ( 'cols' , opt . cols ? opt . cols : null , 'number' ) ; this . _checkType ( 'rows' , opt . rows ? opt . rows : null , 'number' ) ; this . _checkType ( 'cwd' , opt . cwd ? opt . cwd : null , 'string' ) ; this . _checkType ( 'env' , opt . env ? opt . env : null , 'object' ) ; this . _checkType ( 'uid' , opt . uid ? opt . uid : null , 'number' ) ; this . _checkType ( 'gid' , opt . gid ? opt . gid : null , 'number' ) ; this . _checkType ( 'encoding' , opt . encoding ? opt . encoding : null , 'string' ) ; } private _checkType ( name , value , type ) { if ( value && typeof value !== type ) { throw new Error ( `${ name } must be a ${ type } (not a ${ typeof value })` ) ; } } /** See net.Socket.end */ public end ( data ) { this . _socket . end ( data ) ; } /** See stream.Readable.pipe */ public pipe ( dest , options ) { return this . _socket . pipe ( dest , options ) ; } /** See net.Socket.pause */ public pause ( ) { return this . _socket . pause ( ) ; } /** See net.Socket.resume */ public resume ( ) { return this . _socket . resume ( ) ; } /** See net.Socket.setEncoding */ public setEncoding ( encoding ) { if ( ( < any > this . _socket ) . _decoder ) { delete ( < any > this . _socket ) . _decoder ; } if ( encoding ) { this . _socket . setEncoding ( encoding ) ; } } public addListener ( eventName , listener ) { this . on ( eventName , listener ) ; } public on ( eventName , listener ) { if ( eventName === 'close' ) { this . _internalee . on ( 'close' , listener ) ; return ; } this . _socket . on ( eventName , listener ) ; } public emit ( eventName , ... args ) { if ( eventName === 'close' ) { return this . _internalee . emit . apply ( this . _internalee , arguments ) ; } return this . _socket . emit . apply ( this . _socket , arguments ) ; } public listeners ( eventName ) { return this . _socket . listeners ( eventName ) ; } public removeListener ( eventName , listener ) { this . _socket . removeListener ( eventName , listener ) ; } public removeAllListeners ( eventName ) { this . _socket . removeAllListeners ( eventName ) ; } public once ( eventName , listener ) { this . _socket . once ( eventName , listener ) ; } public abstract write ( data ) ; public abstract resize ( cols , rows ) ; public abstract destroy ( ) ; public abstract kill ( signal ? ) ; public abstract get process ( ) : string ; public abstract get master ( ) : Socket ; public abstract get slave ( ) : Socket ; protected _close ( ) { this . _socket . writable = false ; this . _socket . readable = false ; this . write = ( ) => { } ; this . end = ( ) => { } ; this . _writable = false ; this . _readable = false ; } protected _parseEnv ( env ) { const keys = Object . keys ( env || { } ) ; const pairs = [ ] ; for ( let i = 0 ; i < keys . length ; i ++ ) { pairs . push ( keys [ i ] + '=' + env [ keys [ i ] ] ) ; } return pairs ; } }