node-pty 1.1.0-beta41 → 1.1.0-beta43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +2 -0
- package/lib/unixTerminal.js +79 -1
- package/lib/unixTerminal.js.map +1 -1
- package/package.json +1 -1
- package/src/unix/pty.cc +8 -8
- package/src/unixTerminal.ts +97 -3
package/binding.gyp
CHANGED
package/lib/unixTerminal.js
CHANGED
|
@@ -14,6 +14,12 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
14
14
|
})();
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.UnixTerminal = void 0;
|
|
17
|
+
/**
|
|
18
|
+
* Copyright (c) 2012-2015, Christopher Jeffrey (MIT License)
|
|
19
|
+
* Copyright (c) 2016, Daniel Imms (MIT License).
|
|
20
|
+
* Copyright (c) 2018, Microsoft Corporation (MIT License).
|
|
21
|
+
*/
|
|
22
|
+
var fs = require("fs");
|
|
17
23
|
var path = require("path");
|
|
18
24
|
var tty = require("tty");
|
|
19
25
|
var terminal_1 = require("./terminal");
|
|
@@ -88,6 +94,7 @@ var UnixTerminal = /** @class */ (function (_super) {
|
|
|
88
94
|
if (encoding !== null) {
|
|
89
95
|
_this._socket.setEncoding(encoding);
|
|
90
96
|
}
|
|
97
|
+
_this._writeStream = new CustomWriteStream(term.fd, (encoding || undefined));
|
|
91
98
|
// setup
|
|
92
99
|
_this._socket.on('error', function (err) {
|
|
93
100
|
// NOTE: fs.ReadStream gets EAGAIN twice at first:
|
|
@@ -146,7 +153,7 @@ var UnixTerminal = /** @class */ (function (_super) {
|
|
|
146
153
|
configurable: true
|
|
147
154
|
});
|
|
148
155
|
UnixTerminal.prototype._write = function (data) {
|
|
149
|
-
this.
|
|
156
|
+
this._writeStream.write(data);
|
|
150
157
|
};
|
|
151
158
|
Object.defineProperty(UnixTerminal.prototype, "fd", {
|
|
152
159
|
/* Accessors */
|
|
@@ -214,6 +221,7 @@ var UnixTerminal = /** @class */ (function (_super) {
|
|
|
214
221
|
_this.kill('SIGHUP');
|
|
215
222
|
});
|
|
216
223
|
this._socket.destroy();
|
|
224
|
+
this._writeStream.dispose();
|
|
217
225
|
};
|
|
218
226
|
UnixTerminal.prototype.kill = function (signal) {
|
|
219
227
|
try {
|
|
@@ -265,4 +273,74 @@ var UnixTerminal = /** @class */ (function (_super) {
|
|
|
265
273
|
return UnixTerminal;
|
|
266
274
|
}(terminal_1.Terminal));
|
|
267
275
|
exports.UnixTerminal = UnixTerminal;
|
|
276
|
+
/**
|
|
277
|
+
* A custom write stream that writes directly to a file descriptor with proper
|
|
278
|
+
* handling of backpressure and errors. This avoids some event loop exhaustion
|
|
279
|
+
* issues that can occur when using the standard APIs in Node.
|
|
280
|
+
*/
|
|
281
|
+
var CustomWriteStream = /** @class */ (function () {
|
|
282
|
+
function CustomWriteStream(_fd, _encoding) {
|
|
283
|
+
this._fd = _fd;
|
|
284
|
+
this._encoding = _encoding;
|
|
285
|
+
this._writeQueue = [];
|
|
286
|
+
}
|
|
287
|
+
CustomWriteStream.prototype.dispose = function () {
|
|
288
|
+
clearImmediate(this._writeImmediate);
|
|
289
|
+
this._writeImmediate = undefined;
|
|
290
|
+
};
|
|
291
|
+
CustomWriteStream.prototype.write = function (data) {
|
|
292
|
+
// Writes are put in a queue and processed asynchronously in order to handle
|
|
293
|
+
// backpressure from the kernel buffer.
|
|
294
|
+
var buffer = typeof data === 'string'
|
|
295
|
+
? Buffer.from(data, this._encoding)
|
|
296
|
+
: Buffer.from(data);
|
|
297
|
+
if (buffer.byteLength !== 0) {
|
|
298
|
+
this._writeQueue.push({ buffer: buffer, offset: 0 });
|
|
299
|
+
if (this._writeQueue.length === 1) {
|
|
300
|
+
this._processWriteQueue();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
CustomWriteStream.prototype._processWriteQueue = function () {
|
|
305
|
+
var _this = this;
|
|
306
|
+
this._writeImmediate = undefined;
|
|
307
|
+
if (this._writeQueue.length === 0) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
var task = this._writeQueue[0];
|
|
311
|
+
// Write to the underlying file descriptor and handle it directly, rather
|
|
312
|
+
// than using the `net.Socket`/`tty.WriteStream` wrappers which swallow and
|
|
313
|
+
// mask errors like EAGAIN and can cause the thread to block indefinitely.
|
|
314
|
+
fs.write(this._fd, task.buffer, task.offset, function (err, written) {
|
|
315
|
+
if (err) {
|
|
316
|
+
if ('code' in err && err.code === 'EAGAIN') {
|
|
317
|
+
// `setImmediate` is used to yield to the event loop and re-attempt
|
|
318
|
+
// the write later.
|
|
319
|
+
_this._writeImmediate = setImmediate(function () { return _this._processWriteQueue(); });
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Stop processing immediately on unexpected error and log
|
|
323
|
+
_this._writeQueue.length = 0;
|
|
324
|
+
console.error('Unhandled pty write error', err);
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
task.offset += written;
|
|
329
|
+
if (task.offset >= task.buffer.byteLength) {
|
|
330
|
+
_this._writeQueue.shift();
|
|
331
|
+
}
|
|
332
|
+
// Since there is more room in the kernel buffer, we can continue to write
|
|
333
|
+
// until we hit EAGAIN or exhaust the queue.
|
|
334
|
+
//
|
|
335
|
+
// Note that old versions of bash, like v3.2 which ships in macOS, appears
|
|
336
|
+
// to have a bug in its readline implementation that causes data
|
|
337
|
+
// corruption when writes to the pty happens too quickly. Instead of
|
|
338
|
+
// trying to workaround that we just accept it so that large pastes are as
|
|
339
|
+
// fast as possible.
|
|
340
|
+
// Context: https://github.com/microsoft/node-pty/issues/833
|
|
341
|
+
_this._processWriteQueue();
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
return CustomWriteStream;
|
|
345
|
+
}());
|
|
268
346
|
//# sourceMappingURL=unixTerminal.js.map
|
package/lib/unixTerminal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unixTerminal.js","sourceRoot":"","sources":["../src/unixTerminal.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"unixTerminal.js","sourceRoot":"","sources":["../src/unixTerminal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/unix/pty.cc
CHANGED
|
@@ -448,10 +448,10 @@ Napi::Value PtyFork(const Napi::CallbackInfo& info) {
|
|
|
448
448
|
}
|
|
449
449
|
#endif
|
|
450
450
|
|
|
451
|
-
Napi::Object obj = Napi::Object::New(napiEnv);
|
|
452
|
-
obj.Set("fd", Napi::Number::New(napiEnv, master));
|
|
453
|
-
obj.Set("pid", Napi::Number::New(napiEnv, pid));
|
|
454
|
-
obj.Set("pty", Napi::String::New(napiEnv, ptsname(master)));
|
|
451
|
+
Napi::Object obj = Napi::Object::New(napiEnv);
|
|
452
|
+
obj.Set("fd", Napi::Number::New(napiEnv, master));
|
|
453
|
+
obj.Set("pid", Napi::Number::New(napiEnv, pid));
|
|
454
|
+
obj.Set("pty", Napi::String::New(napiEnv, ptsname(master)));
|
|
455
455
|
|
|
456
456
|
// Set up process exit callback.
|
|
457
457
|
Napi::Function cb = info[10].As<Napi::Function>();
|
|
@@ -492,10 +492,10 @@ Napi::Value PtyOpen(const Napi::CallbackInfo& info) {
|
|
|
492
492
|
throw Napi::Error::New(env, "Could not set slave fd to nonblocking.");
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
-
Napi::Object obj = Napi::Object::New(env);
|
|
496
|
-
obj.Set("master", Napi::Number::New(env, master));
|
|
497
|
-
obj.Set("slave", Napi::Number::New(env, slave));
|
|
498
|
-
obj.Set("pty", Napi::String::New(env, ptsname(master)));
|
|
495
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
496
|
+
obj.Set("master", Napi::Number::New(env, master));
|
|
497
|
+
obj.Set("slave", Napi::Number::New(env, slave));
|
|
498
|
+
obj.Set("pty", Napi::String::New(env, ptsname(master)));
|
|
499
499
|
|
|
500
500
|
return obj;
|
|
501
501
|
}
|
package/src/unixTerminal.ts
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* Copyright (c) 2016, Daniel Imms (MIT License).
|
|
4
4
|
* Copyright (c) 2018, Microsoft Corporation (MIT License).
|
|
5
5
|
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
6
7
|
import * as net from 'net';
|
|
7
8
|
import * as path from 'path';
|
|
8
9
|
import * as tty from 'tty';
|
|
9
10
|
import { Terminal, DEFAULT_COLS, DEFAULT_ROWS } from './terminal';
|
|
10
11
|
import { IProcessEnv, IPtyForkOptions, IPtyOpenOptions } from './interfaces';
|
|
11
|
-
import { ArgvOrCommandLine } from './types';
|
|
12
|
+
import { ArgvOrCommandLine, IDisposable } from './types';
|
|
12
13
|
import { assign, loadNativeModule } from './utils';
|
|
13
14
|
|
|
14
15
|
const native = loadNativeModule('pty');
|
|
@@ -34,6 +35,9 @@ export class UnixTerminal extends Terminal {
|
|
|
34
35
|
|
|
35
36
|
private _boundClose: boolean = false;
|
|
36
37
|
private _emittedClose: boolean = false;
|
|
38
|
+
|
|
39
|
+
private _writeStream: CustomWriteStream;
|
|
40
|
+
|
|
37
41
|
private _master: net.Socket | undefined;
|
|
38
42
|
private _slave: net.Socket | undefined;
|
|
39
43
|
|
|
@@ -105,6 +109,7 @@ export class UnixTerminal extends Terminal {
|
|
|
105
109
|
if (encoding !== null) {
|
|
106
110
|
this._socket.setEncoding(encoding);
|
|
107
111
|
}
|
|
112
|
+
this._writeStream = new CustomWriteStream(term.fd, (encoding || undefined) as BufferEncoding);
|
|
108
113
|
|
|
109
114
|
// setup
|
|
110
115
|
this._socket.on('error', (err: any) => {
|
|
@@ -162,7 +167,7 @@ export class UnixTerminal extends Terminal {
|
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
protected _write(data: string | Buffer): void {
|
|
165
|
-
this.
|
|
170
|
+
this._writeStream.write(data);
|
|
166
171
|
}
|
|
167
172
|
|
|
168
173
|
/* Accessors */
|
|
@@ -238,6 +243,7 @@ export class UnixTerminal extends Terminal {
|
|
|
238
243
|
});
|
|
239
244
|
|
|
240
245
|
this._socket.destroy();
|
|
246
|
+
this._writeStream.dispose();
|
|
241
247
|
}
|
|
242
248
|
|
|
243
249
|
public kill(signal?: string): void {
|
|
@@ -252,7 +258,7 @@ export class UnixTerminal extends Terminal {
|
|
|
252
258
|
public get process(): string {
|
|
253
259
|
if (process.platform === 'darwin') {
|
|
254
260
|
const title = pty.process(this._fd);
|
|
255
|
-
return (title !== 'kernel_task'
|
|
261
|
+
return (title !== 'kernel_task') ? title : this._file;
|
|
256
262
|
}
|
|
257
263
|
|
|
258
264
|
return pty.process(this._fd, this._pty) || this._file;
|
|
@@ -292,3 +298,91 @@ export class UnixTerminal extends Terminal {
|
|
|
292
298
|
delete env['LINES'];
|
|
293
299
|
}
|
|
294
300
|
}
|
|
301
|
+
|
|
302
|
+
interface IWriteTask {
|
|
303
|
+
/** The buffer being written. */
|
|
304
|
+
buffer: Buffer;
|
|
305
|
+
/** The current offset of not yet written data. */
|
|
306
|
+
offset: number;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* A custom write stream that writes directly to a file descriptor with proper
|
|
311
|
+
* handling of backpressure and errors. This avoids some event loop exhaustion
|
|
312
|
+
* issues that can occur when using the standard APIs in Node.
|
|
313
|
+
*/
|
|
314
|
+
class CustomWriteStream implements IDisposable {
|
|
315
|
+
|
|
316
|
+
private readonly _writeQueue: IWriteTask[] = [];
|
|
317
|
+
private _writeImmediate: NodeJS.Immediate | undefined;
|
|
318
|
+
|
|
319
|
+
constructor(
|
|
320
|
+
private readonly _fd: number,
|
|
321
|
+
private readonly _encoding: BufferEncoding
|
|
322
|
+
) {
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
dispose(): void {
|
|
326
|
+
clearImmediate(this._writeImmediate);
|
|
327
|
+
this._writeImmediate = undefined;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
write(data: string | Buffer): void {
|
|
331
|
+
// Writes are put in a queue and processed asynchronously in order to handle
|
|
332
|
+
// backpressure from the kernel buffer.
|
|
333
|
+
const buffer = typeof data === 'string'
|
|
334
|
+
? Buffer.from(data, this._encoding)
|
|
335
|
+
: Buffer.from(data);
|
|
336
|
+
|
|
337
|
+
if (buffer.byteLength !== 0) {
|
|
338
|
+
this._writeQueue.push({ buffer, offset: 0 });
|
|
339
|
+
if (this._writeQueue.length === 1) {
|
|
340
|
+
this._processWriteQueue();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private _processWriteQueue(): void {
|
|
346
|
+
this._writeImmediate = undefined;
|
|
347
|
+
|
|
348
|
+
if (this._writeQueue.length === 0) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const task = this._writeQueue[0];
|
|
353
|
+
|
|
354
|
+
// Write to the underlying file descriptor and handle it directly, rather
|
|
355
|
+
// than using the `net.Socket`/`tty.WriteStream` wrappers which swallow and
|
|
356
|
+
// mask errors like EAGAIN and can cause the thread to block indefinitely.
|
|
357
|
+
fs.write(this._fd, task.buffer, task.offset, (err, written) => {
|
|
358
|
+
if (err) {
|
|
359
|
+
if ('code' in err && err.code === 'EAGAIN') {
|
|
360
|
+
// `setImmediate` is used to yield to the event loop and re-attempt
|
|
361
|
+
// the write later.
|
|
362
|
+
this._writeImmediate = setImmediate(() => this._processWriteQueue());
|
|
363
|
+
} else {
|
|
364
|
+
// Stop processing immediately on unexpected error and log
|
|
365
|
+
this._writeQueue.length = 0;
|
|
366
|
+
console.error('Unhandled pty write error', err);
|
|
367
|
+
}
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
task.offset += written;
|
|
372
|
+
if (task.offset >= task.buffer.byteLength) {
|
|
373
|
+
this._writeQueue.shift();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Since there is more room in the kernel buffer, we can continue to write
|
|
377
|
+
// until we hit EAGAIN or exhaust the queue.
|
|
378
|
+
//
|
|
379
|
+
// Note that old versions of bash, like v3.2 which ships in macOS, appears
|
|
380
|
+
// to have a bug in its readline implementation that causes data
|
|
381
|
+
// corruption when writes to the pty happens too quickly. Instead of
|
|
382
|
+
// trying to workaround that we just accept it so that large pastes are as
|
|
383
|
+
// fast as possible.
|
|
384
|
+
// Context: https://github.com/microsoft/node-pty/issues/833
|
|
385
|
+
this._processWriteQueue();
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|