20250118 12:32:34 Waiting for end of input or terminal to close.
20250118 12:32:37 SIGINT, Interrupted system call.
Ewww!

Yeah, MobaXterm (or
something) injects an ETX (
\x03) when the connection is lost, unless the SSH Keepalive setting is enabled.
(In theory, it could be somewhere else in the process chain, but because the setting seems to fix the issue, I'd wager it is MobaXterm. There is a possibility it is actually
sshd on the Linux side, if the actual cause is that without keepalive, MobaXterm may send
incomplete SSH packets; i.e. that the SSH server kills the connection due to what it sees as
bad data; the reason keepalive would fix this is that it somehow ensures that application-internal buffers are flushed to the TCP/IP connection through the TLS layer at packet boundaries... but to verify, I'd need to see MobaXterm sources, which aren't publicly available. Anyway, if one installed the handlers as SA_SIGINFO, with
(int signo, siginfo_t *info, void *context), then
info->si_code would be
SI_KERNEL if it indeed came from the tty layer, or
SI_USER if it was sent by
kill with
info->si_pid identifying the sending process.)
I posted the program and this post just to show the technique I use to solve these kinds of mysteries. It is a simple procedure, but can take an annoying amount of time (due to having to write the test program, and then reproduce the problem, then refine the catching program iteratively to find out further info –– myself not limited by spent time much nowadays), and it relies on
reliably reproducing the issue. One starts by identifying the way the problem occurs –– here, what signal kills the process; what kind of situation causes the target process to exit ––, then testing exactly how that happens (by obtaining further info from the killing signal), and finally by isolating the cause of that signal.
In this case, we skipped directly to isolating the cause. I knew the error message was associated with MobaXterm (I know it because it has pretty good remote graphics support; X11, RDP, and VNC at least), and a quick search associated it with SSH keepalive, so I discovered the configuration setting involved.
(A decade to almost two ago, I volunteered maintaining an installation of IHMC CmapServer – part of
CmapTools written in Java – for an university department of education, and often had to use a Windows workstation to connect to the Linux server using X11. I might have used MobaXterm around 2011, but am not absolutely certain. That installation was quite funky, too: the original instructions wanted to install the closed-source Java stuff as root on Linux, but paranoid me will not! So, I ran it as a non-privileged user in a sandbox-like environment, with Apache as a reverse proxy and providing SSL/TLS security for connections to the service. Worked like a charm quite reliably for years. Nowadays, I'd absolutely recommend implementing the client side in HTML+CSS+JavaScript with active server connections using WebSockets, with server side WebSocket stuff (collaboration) proxied via Nginx/Apache to a service daemon run unprivileged; could even write that in Python for portability. No Java.)