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 |
|
18 |
|
19 |
|
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 |
|
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 = (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 |
|
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 | env.PWD = cwd;
|
63 | var name = opt.name || env.TERM || DEFAULT_NAME;
|
64 | env.TERM = name;
|
65 | var parsedEnv = _this._parseEnv(env);
|
66 | var encoding = (opt.encoding === undefined ? 'utf8' : opt.encoding);
|
67 | var onexit = function (code, signal) {
|
68 |
|
69 |
|
70 | if (!_this._emittedClose) {
|
71 | if (_this._boundClose) {
|
72 | return;
|
73 | }
|
74 | _this._boundClose = true;
|
75 |
|
76 |
|
77 |
|
78 | var timeout_1 = setTimeout(function () {
|
79 | timeout_1 = null;
|
80 |
|
81 | _this._socket.destroy();
|
82 | }, DESTROY_SOCKET_TIMEOUT_MS);
|
83 | _this.once('close', function () {
|
84 | if (timeout_1 !== null) {
|
85 | clearTimeout(timeout_1);
|
86 | }
|
87 | _this.emit('exit', code, signal);
|
88 | });
|
89 | return;
|
90 | }
|
91 | _this.emit('exit', code, signal);
|
92 | };
|
93 |
|
94 | var term = pty.fork(file, args, parsedEnv, cwd, _this._cols, _this._rows, uid, gid, (encoding === 'utf8'), onexit);
|
95 | _this._socket = new PipeSocket(term.fd);
|
96 | if (encoding !== null) {
|
97 | _this._socket.setEncoding(encoding);
|
98 | }
|
99 |
|
100 | _this._socket.on('error', function (err) {
|
101 |
|
102 | if (err.code) {
|
103 | if (~err.code.indexOf('EAGAIN')) {
|
104 | return;
|
105 | }
|
106 | }
|
107 |
|
108 | _this._close();
|
109 |
|
110 | if (!_this._emittedClose) {
|
111 | _this._emittedClose = true;
|
112 | _this.emit('close');
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | if (err.code) {
|
119 | if (~err.code.indexOf('errno 5') || ~err.code.indexOf('EIO')) {
|
120 | return;
|
121 | }
|
122 | }
|
123 |
|
124 | if (_this.listeners('error').length < 2) {
|
125 | throw err;
|
126 | }
|
127 | });
|
128 | _this._pid = term.pid;
|
129 | _this._fd = term.fd;
|
130 | _this._pty = term.pty;
|
131 | _this._file = file;
|
132 | _this._name = name;
|
133 | _this._readable = true;
|
134 | _this._writable = true;
|
135 | _this._socket.on('close', function () {
|
136 | if (_this._emittedClose) {
|
137 | return;
|
138 | }
|
139 | _this._emittedClose = true;
|
140 | _this._close();
|
141 | _this.emit('close');
|
142 | });
|
143 | _this._forwardEvents();
|
144 | return _this;
|
145 | }
|
146 | Object.defineProperty(UnixTerminal.prototype, "master", {
|
147 | get: function () { return this._master; },
|
148 | enumerable: true,
|
149 | configurable: true
|
150 | });
|
151 | Object.defineProperty(UnixTerminal.prototype, "slave", {
|
152 | get: function () { return this._slave; },
|
153 | enumerable: true,
|
154 | configurable: true
|
155 | });
|
156 | UnixTerminal.prototype._write = function (data) {
|
157 | this._socket.write(data);
|
158 | };
|
159 | |
160 |
|
161 |
|
162 | UnixTerminal.open = function (opt) {
|
163 | var self = Object.create(UnixTerminal.prototype);
|
164 | opt = opt || {};
|
165 | if (arguments.length > 1) {
|
166 | opt = {
|
167 | cols: arguments[1],
|
168 | rows: arguments[2]
|
169 | };
|
170 | }
|
171 | var cols = opt.cols || terminal_1.DEFAULT_COLS;
|
172 | var rows = opt.rows || terminal_1.DEFAULT_ROWS;
|
173 | var encoding = (opt.encoding === undefined ? 'utf8' : opt.encoding);
|
174 |
|
175 | var term = pty.open(cols, rows);
|
176 | self._master = new PipeSocket(term.master);
|
177 | if (encoding !== null) {
|
178 | self._master.setEncoding(encoding);
|
179 | }
|
180 | self._master.resume();
|
181 | self._slave = new PipeSocket(term.slave);
|
182 | if (encoding !== null) {
|
183 | self._slave.setEncoding(encoding);
|
184 | }
|
185 | self._slave.resume();
|
186 | self._socket = self._master;
|
187 | self._pid = null;
|
188 | self._fd = term.master;
|
189 | self._pty = term.pty;
|
190 | self._file = process.argv[0] || 'node';
|
191 | self._name = process.env.TERM || '';
|
192 | self._readable = true;
|
193 | self._writable = true;
|
194 | self._socket.on('error', function (err) {
|
195 | self._close();
|
196 | if (self.listeners('error').length < 2) {
|
197 | throw err;
|
198 | }
|
199 | });
|
200 | self._socket.on('close', function () {
|
201 | self._close();
|
202 | });
|
203 | return self;
|
204 | };
|
205 | UnixTerminal.prototype.destroy = function () {
|
206 | var _this = this;
|
207 | this._close();
|
208 |
|
209 |
|
210 | this._socket.once('close', function () {
|
211 | _this.kill('SIGHUP');
|
212 | });
|
213 | this._socket.destroy();
|
214 | };
|
215 | UnixTerminal.prototype.kill = function (signal) {
|
216 | try {
|
217 | process.kill(this.pid, signal || 'SIGHUP');
|
218 | }
|
219 | catch (e) { }
|
220 | };
|
221 | Object.defineProperty(UnixTerminal.prototype, "process", {
|
222 | |
223 |
|
224 |
|
225 | get: function () {
|
226 | return pty.process(this._fd, this._pty) || this._file;
|
227 | },
|
228 | enumerable: true,
|
229 | configurable: true
|
230 | });
|
231 | |
232 |
|
233 |
|
234 | UnixTerminal.prototype.resize = function (cols, rows) {
|
235 | if (cols <= 0 || rows <= 0 || isNaN(cols) || isNaN(rows) || cols === Infinity || rows === Infinity) {
|
236 | throw new Error('resizing must be done using positive cols and rows');
|
237 | }
|
238 | pty.resize(this._fd, cols, rows);
|
239 | this._cols = cols;
|
240 | this._rows = rows;
|
241 | };
|
242 | UnixTerminal.prototype._sanitizeEnv = function (env) {
|
243 |
|
244 | delete env['TMUX'];
|
245 | delete env['TMUX_PANE'];
|
246 |
|
247 |
|
248 | delete env['STY'];
|
249 | delete env['WINDOW'];
|
250 |
|
251 | delete env['WINDOWID'];
|
252 | delete env['TERMCAP'];
|
253 | delete env['COLUMNS'];
|
254 | delete env['LINES'];
|
255 | };
|
256 | return UnixTerminal;
|
257 | }(terminal_1.Terminal));
|
258 | exports.UnixTerminal = UnixTerminal;
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 | var PipeSocket = (function (_super) {
|
265 | __extends(PipeSocket, _super);
|
266 | function PipeSocket(fd) {
|
267 | var _this = this;
|
268 | var pipeWrap = process.binding('pipe_wrap');
|
269 |
|
270 | var handle = new pipeWrap.Pipe(pipeWrap.constants.SOCKET);
|
271 | handle.open(fd);
|
272 | _this = _super.call(this, { handle: handle }) || this;
|
273 | return _this;
|
274 | }
|
275 | return PipeSocket;
|
276 | }(net.Socket));
|
277 |
|
\ | No newline at end of file |