node-pty icon indicating copy to clipboard operation
node-pty copied to clipboard

pty doesn't respect flowing mode like net.Socket/stream.Readable

Open Et7f3 opened this issue 1 year ago • 0 comments
trafficstars

Environment details

  • OS: Linux
  • OS version: 5.15.0-82-generic
  • node-pty version: 1.0.0

Issue description

From Stream I expect to see my string displayed because I fall in the edge case.

$ node -e "
const node_pty = require('node-pty');
const pty = node_pty.spawn('bash', [ '-c', 'echo somet${nothing}hing' ]);
pty.pause();
setTimeout(() => { pty._socket.on('data', console.log); pty.on('data', console.log); pty.resume(); console.log('data is lost'); }, 2000);
"
data is lost

I see that PipeSocket inherit from net.Socket and it mention that data is dropped if no listener:

The data will be lost if there is no listener when a Socket emits a 'data' event.

https://nodejs.org/api/net.html#event-data however this seems like it is untouched since "v0.1.90" so most likely wrong. I just opened an upstream issue to confirm.

I tried to debug and here are my findings: node-pty add a data handler with code that emulate EventEmitter (with EventEmitter2) https://github.com/microsoft/node-pty/blob/d6ce76a801f68730f7204b7b27bb21dbf8e63001/src/terminal.ts#L96 Is their a particular reason to recreate this code path with no value added (it simply forward argument) maybe a POO quircks.

When we strace we see the data is read by node so the data is lost between nodejs runtime and node-pty.

$ strace -f -e /write,read node -e "
const node_pty = require('node-pty');
const pty = node_pty.spawn('bash', [ '-c', 'echo somet${nothing}hing' ]);
pty.pause();
setTimeout(() => { pty._socket.on('data', console.log); pty.on('data', console.log); pty.resume(); console.log('data is lost'); }, 2000);
" 2>&1 | grep something
[pid 785556] write(1, "something\n", 10) = 10
[pid 785546] read(23, "something\r\n", 65536) = 11

(I added ${nothing} to be sure we read the output produce by bash)

Et7f3 avatar Dec 24 '23 05:12 Et7f3