installed pty
[VSoRC/.git] / node_modules / node-pty / lib / unixTerminal.js
1 "use strict";
2 var __extends = (this && this.__extends) || (function () {
3     var extendStatics = function (d, b) {
4         extendStatics = Object.setPrototypeOf ||
5             ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6             function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7         return extendStatics(d, b);
8     };
9     return function (d, b) {
10         extendStatics(d, b);
11         function __() { this.constructor = d; }
12         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13     };
14 })();
15 Object.defineProperty(exports, "__esModule", { value: true });
16 /**
17  * Copyright (c) 2012-2015, Christopher Jeffrey (MIT License)
18  * Copyright (c) 2016, Daniel Imms (MIT License).
19  * Copyright (c) 2018, Microsoft Corporation (MIT License).
20  */
21 var net = require("net");
22 var terminal_1 = require("./terminal");
23 var utils_1 = require("./utils");
24 var pty;
25 try {
26     pty = require('../build/Release/pty.node');
27 }
28 catch (outerError) {
29     try {
30         pty = require('../build/Debug/pty.node');
31     }
32     catch (innerError) {
33         console.error('innerError', innerError);
34         // Re-throw the exception from the Release require if the Debug require fails as well
35         throw outerError;
36     }
37 }
38 var DEFAULT_FILE = 'sh';
39 var DEFAULT_NAME = 'xterm';
40 var DESTROY_SOCKET_TIMEOUT_MS = 200;
41 var UnixTerminal = /** @class */ (function (_super) {
42     __extends(UnixTerminal, _super);
43     function UnixTerminal(file, args, opt) {
44         var _this = _super.call(this, opt) || this;
45         if (typeof args === 'string') {
46             throw new Error('args as a string is not supported on unix.');
47         }
48         // Initialize arguments
49         args = args || [];
50         file = file || DEFAULT_FILE;
51         opt = opt || {};
52         opt.env = opt.env || process.env;
53         _this._cols = opt.cols || terminal_1.DEFAULT_COLS;
54         _this._rows = opt.rows || terminal_1.DEFAULT_ROWS;
55         var uid = opt.uid || -1;
56         var gid = opt.gid || -1;
57         var env = utils_1.assign({}, opt.env);
58         if (opt.env === process.env) {
59             _this._sanitizeEnv(env);
60         }
61         var cwd = opt.cwd || process.cwd();
62         var name = opt.name || env.TERM || DEFAULT_NAME;
63         env.TERM = name;
64         var parsedEnv = _this._parseEnv(env);
65         var encoding = (opt.encoding === undefined ? 'utf8' : opt.encoding);
66         var onexit = function (code, signal) {
67             // XXX Sometimes a data event is emitted after exit. Wait til socket is
68             // destroyed.
69             if (!_this._emittedClose) {
70                 if (_this._boundClose) {
71                     return;
72                 }
73                 _this._boundClose = true;
74                 // From macOS High Sierra 10.13.2 sometimes the socket never gets
75                 // closed. A timeout is applied here to avoid the terminal never being
76                 // destroyed when this occurs.
77                 var timeout_1 = setTimeout(function () {
78                     timeout_1 = null;
79                     // Destroying the socket now will cause the close event to fire
80                     _this._socket.destroy();
81                 }, DESTROY_SOCKET_TIMEOUT_MS);
82                 _this.once('close', function () {
83                     if (timeout_1 !== null) {
84                         clearTimeout(timeout_1);
85                     }
86                     _this.emit('exit', code, signal);
87                 });
88                 return;
89             }
90             _this.emit('exit', code, signal);
91         };
92         // fork
93         var term = pty.fork(file, args, parsedEnv, cwd, _this._cols, _this._rows, uid, gid, (encoding === 'utf8'), onexit);
94         _this._socket = new PipeSocket(term.fd);
95         if (encoding !== null) {
96             _this._socket.setEncoding(encoding);
97         }
98         // setup
99         _this._socket.on('error', function (err) {
100             // NOTE: fs.ReadStream gets EAGAIN twice at first:
101             if (err.code) {
102                 if (~err.code.indexOf('EAGAIN')) {
103                     return;
104                 }
105             }
106             // close
107             _this._close();
108             // EIO on exit from fs.ReadStream:
109             if (!_this._emittedClose) {
110                 _this._emittedClose = true;
111                 _this.emit('close');
112             }
113             // EIO, happens when someone closes our child process: the only process in
114             // the terminal.
115             // node < 0.6.14: errno 5
116             // node >= 0.6.14: read EIO
117             if (err.code) {
118                 if (~err.code.indexOf('errno 5') || ~err.code.indexOf('EIO')) {
119                     return;
120                 }
121             }
122             // throw anything else
123             if (_this.listeners('error').length < 2) {
124                 throw err;
125             }
126         });
127         _this._pid = term.pid;
128         _this._fd = term.fd;
129         _this._pty = term.pty;
130         _this._file = file;
131         _this._name = name;
132         _this._readable = true;
133         _this._writable = true;
134         _this._socket.on('close', function () {
135             if (_this._emittedClose) {
136                 return;
137             }
138             _this._emittedClose = true;
139             _this._close();
140             _this.emit('close');
141         });
142         _this._forwardEvents();
143         return _this;
144     }
145     Object.defineProperty(UnixTerminal.prototype, "master", {
146         get: function () { return this._master; },
147         enumerable: true,
148         configurable: true
149     });
150     Object.defineProperty(UnixTerminal.prototype, "slave", {
151         get: function () { return this._slave; },
152         enumerable: true,
153         configurable: true
154     });
155     UnixTerminal.prototype._write = function (data) {
156         this._socket.write(data);
157     };
158     /**
159      * openpty
160      */
161     UnixTerminal.open = function (opt) {
162         var self = Object.create(UnixTerminal.prototype);
163         opt = opt || {};
164         if (arguments.length > 1) {
165             opt = {
166                 cols: arguments[1],
167                 rows: arguments[2]
168             };
169         }
170         var cols = opt.cols || terminal_1.DEFAULT_COLS;
171         var rows = opt.rows || terminal_1.DEFAULT_ROWS;
172         var encoding = (opt.encoding === undefined ? 'utf8' : opt.encoding);
173         // open
174         var term = pty.open(cols, rows);
175         self._master = new PipeSocket(term.master);
176         if (encoding !== null) {
177             self._master.setEncoding(encoding);
178         }
179         self._master.resume();
180         self._slave = new PipeSocket(term.slave);
181         if (encoding !== null) {
182             self._slave.setEncoding(encoding);
183         }
184         self._slave.resume();
185         self._socket = self._master;
186         self._pid = null;
187         self._fd = term.master;
188         self._pty = term.pty;
189         self._file = process.argv[0] || 'node';
190         self._name = process.env.TERM || '';
191         self._readable = true;
192         self._writable = true;
193         self._socket.on('error', function (err) {
194             self._close();
195             if (self.listeners('error').length < 2) {
196                 throw err;
197             }
198         });
199         self._socket.on('close', function () {
200             self._close();
201         });
202         return self;
203     };
204     UnixTerminal.prototype.destroy = function () {
205         var _this = this;
206         this._close();
207         // Need to close the read stream so node stops reading a dead file
208         // descriptor. Then we can safely SIGHUP the shell.
209         this._socket.once('close', function () {
210             _this.kill('SIGHUP');
211         });
212         this._socket.destroy();
213     };
214     UnixTerminal.prototype.kill = function (signal) {
215         try {
216             process.kill(this.pid, signal || 'SIGHUP');
217         }
218         catch (e) { /* swallow */ }
219     };
220     Object.defineProperty(UnixTerminal.prototype, "process", {
221         /**
222          * Gets the name of the process.
223          */
224         get: function () {
225             return pty.process(this._fd, this._pty) || this._file;
226         },
227         enumerable: true,
228         configurable: true
229     });
230     /**
231      * TTY
232      */
233     UnixTerminal.prototype.resize = function (cols, rows) {
234         if (cols <= 0 || rows <= 0 || isNaN(cols) || isNaN(rows) || cols === Infinity || rows === Infinity) {
235             throw new Error('resizing must be done using positive cols and rows');
236         }
237         pty.resize(this._fd, cols, rows);
238         this._cols = cols;
239         this._rows = rows;
240     };
241     UnixTerminal.prototype._sanitizeEnv = function (env) {
242         // Make sure we didn't start our server from inside tmux.
243         delete env['TMUX'];
244         delete env['TMUX_PANE'];
245         // Make sure we didn't start our server from inside screen.
246         // http://web.mit.edu/gnu/doc/html/screen_20.html
247         delete env['STY'];
248         delete env['WINDOW'];
249         // Delete some variables that might confuse our terminal.
250         delete env['WINDOWID'];
251         delete env['TERMCAP'];
252         delete env['COLUMNS'];
253         delete env['LINES'];
254     };
255     return UnixTerminal;
256 }(terminal_1.Terminal));
257 exports.UnixTerminal = UnixTerminal;
258 /**
259  * Wraps net.Socket to force the handle type "PIPE" by temporarily overwriting
260  * tty_wrap.guessHandleType.
261  * See: https://github.com/chjj/pty.js/issues/103
262  */
263 var PipeSocket = /** @class */ (function (_super) {
264     __extends(PipeSocket, _super);
265     function PipeSocket(fd) {
266         var _this = this;
267         var _a = process.binding('pipe_wrap'), Pipe = _a.Pipe, constants = _a.constants; // tslint:disable-line
268         // @types/node has fd as string? https://github.com/DefinitelyTyped/DefinitelyTyped/pull/18275
269         var handle = new Pipe(constants.SOCKET);
270         handle.open(fd);
271         _this = _super.call(this, { handle: handle }) || this;
272         return _this;
273     }
274     return PipeSocket;
275 }(net.Socket));
276 //# sourceMappingURL=unixTerminal.js.map