ekzhang / sshx

Fast, collaborative live terminal sharing over the web
https://sshx.io
MIT License
5.8k stars 175 forks source link

Terminall freezes with nushell #60

Open Slushee-a opened 10 months ago

Slushee-a commented 10 months ago

I started a session on a nushell shell and it defaulted to bash, which did work. When I opened a terminal and tried to run nu on it, that terminal would just freeze. I tried to run it with the --shell nu and --shell /home/slushee/.cargo/bin/nu arguments and any terminal I created on the website would just freeze without giving a prompt.

I wonder if this is an issue with nu not being POSIX compliant, this could be tested with fish.

Current behavior

Terminals which attempt to use the nu shell freeze and don't show any prompt

Expected behavior

The application works the same way as it does with bash and zsh, showing a functional nushell prompt for every terminal opened.

Envoriment

ekzhang commented 10 months ago

Thanks for the detailed bug report including version, browser, nushell and Rust versions. I'm not familiar with nu, and I'm surprised that it wouldn't be working. Not specifically as a shell, but as a terminal program, that's strange that it would behave differently on sshx.

It's possible it could be due to sshx not supporting various ANSI escape sequences for PTY queries like the "Query Cursor Position" sequence. This is because it can replay the output sequence multiple times across users. I'll try and see.

ekzhang commented 10 months ago

I am able to reproduce on macOS Ventura.

ekzhang commented 10 months ago

Ah, well my random hunch was right. Here's the strace output from Alpine Linux (repeats every few seconds, probably stuck in a retry loop internally in nushell):

Steps to reproduce

I'm running in an Alpine Linux, aarch64 container. ```bash docker run -it --rm alpine:3.18.4 ``` Then in Alpine: ```bash apk add curl apk add nushell --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing curl -sSf https://sshx.io/get | sh sshx ``` Inside sshx, open multiple terminals and in one terminal: ```bash echo $$ ``` To get the PID, then run in the second terminal: ```bash strace -f -p $PID ``` And in the first terminal: ```bash nu ```

[pid    76] ioctl(0, TIOCGWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
[pid    76] ioctl(0, TCGETS, {c_iflag=ICRNL|IXON, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = 0
[pid    76] ioctl(0, TCSETS, {c_iflag=, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ECHOE|ECHOK|ECHOCTL|ECHOKE, ...}) = 0
[pid    76] openat(AT_FDCWD, "/dev/tty", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 8
[pid    76] fcntl(8, F_SETFD, FD_CLOEXEC) = 0
[pid    76] ioctl(8, TIOCGWINSZ, {ws_row=24, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
[pid    76] close(8)                    = 0
[pid    76] write(1, "\33[6n", 4)       = 4
[pid    76] epoll_pwait(5, 

\33[6n is the "Device Status Report" (DSR) escape sequence, which requests the cursor position from the terminal. I don't see an immediate way to support this in sshx right now, unfortunately (especially since it's end-to-end encrypted, so the server certainly can't handle it) but maybe we can add something to the client binary that outputs a fake cursor position.

Is there any possibility that the nushell authors would be able to add a fallback for terminals that don't support cursor position reporting?

Slushee-a commented 10 months ago

Is there any possibility that the nushell authors would be able to add a fallback for terminals that don't support cursor position reporting?

It seems like it was a low priority issue last year, but it might be implemented as of now. I can fork sshx tomorrow and attempt to implement the least dodgy workaround possible. If I don't succeed, shall I close this isse?