microsoft / node-pty

Fork pseudoterminals in Node.JS
Other
1.47k stars 239 forks source link

Add a callback to ptyProcess.write #651

Open lysol33 opened 9 months ago

lysol33 commented 9 months ago

Environment details

Issue description

I'm trying to send a response when ptyprocess gets data from PTY, but I'm having concurrency problem with overlapping requests. I think it would be a good option to add a callback to the .write() method with the data recieved from the socket

Et7f3 commented 9 months ago

When you write the data is fully written synchronously to the pty (you can confirm it with strace).

42sh $ strace -f -e /exec,write,read node -e "
const node_pty = require('node-pty');
const pty = node_pty.spawn('/bin/sh');
pty.write('exit 123\n');
" 2>&1 | grep -e exit' 123' -e exec
execve("/nix/store/l43bdmxxlkrzwic3q24ik366qyqg3s1g-nodejs-18.16.1/bin/node", ["node", "-e", "\nconst node_pty = require('node-"...], 0x7ffd5f403928 /* 125 vars */) = 0
[pid 780469] execve("/bin/sh", ["/bin/sh"], 0x336c5d0 /* 125 vars */) = 0
[pid 780459] write(23, "exit 123\n", 9) = 9
[pid 780459] read(23, "exit 123\r\n", 65536) = 10
[pid 780469] write(2, "exit 123", 8)    = 8
[pid 780459] read(23, "exit 123\r\n", 65536) = 10
[pid 780469] write(3, "exit 123\n", 9)  = 9

https://github.com/microsoft/node-pty/blob/d6ce76a801f68730f7204b7b27bb21dbf8e63001/src/terminal.ts#L92 https://github.com/microsoft/node-pty/blob/d6ce76a801f68730f7204b7b27bb21dbf8e63001/src/unixTerminal.ts#L176-L178

It it not because data is written that the other process actually read it (it might be doing other thing)

You might have to do with echo of the tty ?

Can you provide an example where you have issue ?

lysol33 commented 9 months ago

What I need is a way to tell when the TTY driver copies data back to the PTY master I guess. Basically, I don't need the echo of what the user writes to the process, but a signal when a data stream going back to the pty master has ended for the given input. Could this be possible?

Et7f3 commented 9 months ago

In a deleted exemple you spawned a shell and launched ls ? Why not using node:child_process or node-pty and launch directly ls.

Here in context of a shell you can know when the process ended if you detect PS1 (you can set it to a boundary string before launching ls). We can not know when the process stopped in the general case (because it might be sleeping) and signal SIGCHLD is handled by intermediary shell.

lysol33 commented 9 months ago

I'm not sure to be honest. I don't think I will be able to use commands such as 'history' if I use node:child_process?

Et7f3 commented 9 months ago

If your intention is to read history then just fs.readFile .bash_history if shell is bash or %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt if shell is pwsh. You will get better performance no process loading.