node-pty 0.10.0-beta9 → 0.11.0-beta10

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.
Files changed (40) hide show
  1. package/README.md +39 -27
  2. package/binding.gyp +0 -7
  3. package/deps/winpty/src/agent/ConsoleFont.cc +0 -66
  4. package/lib/eventEmitter2.js +2 -1
  5. package/lib/eventEmitter2.js.map +1 -1
  6. package/lib/index.js +1 -0
  7. package/lib/index.js.map +1 -1
  8. package/lib/shared/conout.js +11 -0
  9. package/lib/shared/conout.js.map +1 -0
  10. package/lib/terminal.js +9 -6
  11. package/lib/terminal.js.map +1 -1
  12. package/lib/terminal.test.js +3 -3
  13. package/lib/testUtils.test.js +1 -0
  14. package/lib/testUtils.test.js.map +1 -1
  15. package/lib/unixTerminal.js +4 -3
  16. package/lib/unixTerminal.js.map +1 -1
  17. package/lib/utils.js +1 -0
  18. package/lib/utils.js.map +1 -1
  19. package/lib/windowsConoutConnection.js +122 -0
  20. package/lib/windowsConoutConnection.js.map +1 -0
  21. package/lib/windowsPtyAgent.js +23 -17
  22. package/lib/windowsPtyAgent.js.map +1 -1
  23. package/lib/windowsTerminal.js +4 -3
  24. package/lib/windowsTerminal.js.map +1 -1
  25. package/lib/windowsTerminal.test.js +9 -0
  26. package/lib/windowsTerminal.test.js.map +1 -1
  27. package/lib/worker/conoutSocketWorker.js +19 -0
  28. package/lib/worker/conoutSocketWorker.js.map +1 -0
  29. package/package.json +5 -5
  30. package/src/interfaces.ts +2 -15
  31. package/src/shared/conout.ts +15 -0
  32. package/src/terminal.ts +3 -1
  33. package/src/unixTerminal.ts +1 -1
  34. package/src/win/conpty.cc +28 -20
  35. package/src/win/path_util.cc +1 -1
  36. package/src/windowsConoutConnection.ts +79 -0
  37. package/src/windowsPtyAgent.ts +17 -12
  38. package/src/windowsTerminal.test.ts +10 -0
  39. package/src/worker/conoutSocketWorker.ts +18 -0
  40. package/typings/node-pty.d.ts +15 -5
@@ -4,11 +4,13 @@
4
4
  * Copyright (c) 2018, Microsoft Corporation (MIT License).
5
5
  */
6
6
 
7
+ import * as fs from 'fs';
7
8
  import * as os from 'os';
8
9
  import * as path from 'path';
9
10
  import { Socket } from 'net';
10
11
  import { ArgvOrCommandLine } from './types';
11
12
  import { fork } from 'child_process';
13
+ import { ConoutConnection } from './windowsConoutConnection';
12
14
 
13
15
  let conptyNative: IConptyNative;
14
16
  let winptyNative: IWinptyNative;
@@ -18,7 +20,7 @@ let winptyNative: IWinptyNative;
18
20
  * shutting down the socket. The timer will be reset if a new data event comes in after the timer
19
21
  * has started.
20
22
  */
21
- const FLUSH_DATA_INTERVAL = 20;
23
+ const FLUSH_DATA_INTERVAL = 1000;
22
24
 
23
25
  /**
24
26
  * This agent sits between the WindowsTerminal class and provides a common interface for both conpty
@@ -32,6 +34,7 @@ export class WindowsPtyAgent {
32
34
  private _innerPidHandle: number;
33
35
  private _closeTimeout: NodeJS.Timer;
34
36
  private _exitCode: number | undefined;
37
+ private _conoutSocketWorker: ConoutConnection;
35
38
 
36
39
  private _fd: any;
37
40
  private _pty: number;
@@ -115,17 +118,22 @@ export class WindowsPtyAgent {
115
118
  // Create terminal pipe IPC channel and forward to a local unix socket.
116
119
  this._outSocket = new Socket();
117
120
  this._outSocket.setEncoding('utf8');
118
- this._outSocket.connect(term.conout, () => {
119
- // TODO: Emit event on agent instead of socket?
120
-
121
- // Emit ready event.
121
+ // The conout socket must be ready out on another thread to avoid deadlocks
122
+ this._conoutSocketWorker = new ConoutConnection(term.conout);
123
+ this._conoutSocketWorker.onReady(() => {
124
+ this._conoutSocketWorker.connectSocket(this._outSocket);
125
+ });
126
+ this._outSocket.on('connect', () => {
122
127
  this._outSocket.emit('ready_datapipe');
123
128
  });
124
129
 
125
- this._inSocket = new Socket();
130
+ const inSocketFD = fs.openSync(term.conin, 'w');
131
+ this._inSocket = new Socket({
132
+ fd: inSocketFD,
133
+ readable: false,
134
+ writable: true
135
+ });
126
136
  this._inSocket.setEncoding('utf8');
127
- this._inSocket.connect(term.conin);
128
- // TODO: Wait for ready event?
129
137
 
130
138
  if (this._useConpty) {
131
139
  const connect = (this._ptyNative as IConptyNative).connect(this._pty, commandLine, cwd, env, c => this._$onProcessExit(c));
@@ -146,9 +154,7 @@ export class WindowsPtyAgent {
146
154
 
147
155
  public kill(): void {
148
156
  this._inSocket.readable = false;
149
- this._inSocket.writable = false;
150
157
  this._outSocket.readable = false;
151
- this._outSocket.writable = false;
152
158
  // Tell the agent to kill the pty, this releases handles to the process
153
159
  if (this._useConpty) {
154
160
  this._getConsoleProcessList().then(consoleProcessList => {
@@ -178,6 +184,7 @@ export class WindowsPtyAgent {
178
184
  }
179
185
  });
180
186
  }
187
+ this._conoutSocketWorker.dispose();
181
188
  }
182
189
 
183
190
  private _getConsoleProcessList(): Promise<number[]> {
@@ -233,9 +240,7 @@ export class WindowsPtyAgent {
233
240
 
234
241
  private _cleanUpProcess(): void {
235
242
  this._inSocket.readable = false;
236
- this._inSocket.writable = false;
237
243
  this._outSocket.readable = false;
238
- this._outSocket.writable = false;
239
244
  this._outSocket.destroy();
240
245
  }
241
246
  }
@@ -201,5 +201,15 @@ if (process.platform === 'win32') {
201
201
  });
202
202
  });
203
203
  });
204
+
205
+ describe('winpty', () => {
206
+ it('should accept input', (done) => {
207
+ const term = new WindowsTerminal('cmd.exe', '', { useConpty: false });
208
+ term.write('exit\r');
209
+ term.on('exit', () => {
210
+ done();
211
+ });
212
+ });
213
+ });
204
214
  });
205
215
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2020, Microsoft Corporation (MIT License).
3
+ */
4
+
5
+ import { parentPort, workerData } from 'worker_threads';
6
+ import { Socket, createServer } from 'net';
7
+ import { ConoutWorkerMessage, IWorkerData, getWorkerPipeName } from '../shared/conout';
8
+
9
+ const conoutPipeName = (workerData as IWorkerData).conoutPipeName;
10
+ const conoutSocket = new Socket();
11
+ conoutSocket.setEncoding('utf8');
12
+ conoutSocket.connect(conoutPipeName, () => {
13
+ const server = createServer(workerSocket => {
14
+ conoutSocket.pipe(workerSocket);
15
+ });
16
+ server.listen(getWorkerPipeName(conoutPipeName));
17
+ parentPort.postMessage(ConoutWorkerMessage.READY);
18
+ });
@@ -35,14 +35,14 @@ declare module 'node-pty' {
35
35
  rows?: number;
36
36
 
37
37
  /**
38
- * Working directory to be set for the slave program.
38
+ * Working directory to be set for the child program.
39
39
  */
40
40
  cwd?: string;
41
41
 
42
42
  /**
43
- * Environment to be set for the slave program.
43
+ * Environment to be set for the child program.
44
44
  */
45
- env?: { [key: string]: string };
45
+ env?: { [key: string]: string | undefined };
46
46
 
47
47
  /**
48
48
  * String encoding of the underlying pty.
@@ -55,7 +55,7 @@ declare module 'node-pty' {
55
55
  /**
56
56
  * (EXPERIMENTAL)
57
57
  * Whether to enable flow control handling (false by default). If enabled a message of `flowControlPause`
58
- * will pause the socket and thus blocking the slave program execution due to buffer back pressure.
58
+ * will pause the socket and thus blocking the child program execution due to buffer back pressure.
59
59
  * A message of `flowControlResume` will resume the socket into flow mode.
60
60
  * For performance reasons only a single message as a whole will match (no message part matching).
61
61
  * If flow control is enabled the `flowControlPause` and `flowControlResume` messages are not forwarded to
@@ -79,7 +79,7 @@ declare module 'node-pty' {
79
79
  export interface IPtyForkOptions extends IBasePtyForkOptions {
80
80
  /**
81
81
  * Security warning: use this option with great caution, as opened file descriptors
82
- * with higher privileges might leak to the slave program.
82
+ * with higher privileges might leak to the child program.
83
83
  */
84
84
  uid?: number;
85
85
  gid?: number;
@@ -183,6 +183,16 @@ declare module 'node-pty' {
183
183
  * @throws Will throw when signal is used on Windows.
184
184
  */
185
185
  kill(signal?: string): void;
186
+
187
+ /**
188
+ * Pauses the pty for customizable flow control.
189
+ */
190
+ pause(): void;
191
+
192
+ /**
193
+ * Resumes the pty for customizable flow control.
194
+ */
195
+ resume(): void;
186
196
  }
187
197
 
188
198
  /**