Repository navigation
Conversation
a1ffbc2 to
d08e61a
Compare
|
Thank you for the feedback! I've updated the fix to:
This approach:
The changes ensure that viewer/editor modes can work with pipes while full mc mode still requires a proper terminal. |
|
@mukhanov - thanks for your submission. I've screened it through Opus 5.5, and it has identified a number of issues and suggests a different approach. Would you be up to reviewing and testing the suggested alternative? I can submit the results later this coming week. |
|
Hi @zyv, Yes, I'd be happy to review and test the alternative approach suggested by Opus 5.5. This is indeed a rather annoying bug - mc hanging on startup when stdin is not a terminal is a real problem that needs a proper fix. I'm particularly interested in seeing how Opus 5.5 handles the error cases differently from my initial approach. Looking forward to reviewing the results when you have them ready. Best regards |
MC reads the keyboard from stdin with the ncurses backend, and both
backends save the initial terminal modes from stdin. When stdin is
redirected (e.g. "mc < /dev/null" or "find ... | xargs mcedit", GNU
xargs gives the command /dev/null as stdin):
* the ncurses build busy-loops on EOF, or blocks on a pipe, and does
not react to the keyboard at all;
* the S-Lang build reads the keyboard from /dev/tty, but saves the
"shell" terminal modes from stdin, which fails and leaves them
zero-filled, so every external command is run on a terminal with
speed 0 and no echo, signals or output post-processing.
Before initializing the terminal, attach a redirected stdin to the
controlling terminal, like "xargs -o" does (fall back to stderr like
S-Lang does if there is no controlling terminal), and fail with a
clear message only if there is no terminal at all. MC never reads data
from stdin; a future implementation of reading the viewer data from
stdin (MidnightCommander#2370) will have to dup() the original stdin before this call.
Assisted-By: Claude Opus 5.5
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
Run tty_stdin_to_terminal() in a new session on a fresh pseudo-terminal and check that a key typed on that terminal can be read from stdin when stdin is a terminal, when it is redirected and there is a controlling terminal, and when it is redirected and only stderr is a terminal, and that a failure is reported with stdin left untouched if there is no terminal at all. Assisted-By: Claude Opus 5.5 Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
tty_init() ignored the result of tcgetattr() in both backends:
* ncurses: an uninitialized structure was applied to the terminal
with tcsetattr(). Only change VINTR/VQUIT if the modes were read.
* S-Lang: boot_mode stayed zero-filled and was applied to the
terminal before running every external command (speed 0, no echo,
no signals, no output post-processing). Fail early instead, before
the terminal is touched, like for an unsupported screen size. Also
fail if SLang_init_tty() does, instead of running on a terminal that
S-Lang has not set up.
Assisted-By: Claude Opus 5.5
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
94f0396 to
bf20399
Compare
|
Okay, I have finally managed to process the alternative patch series generated with Opus 5.5, which do make sense to me. It includes a test that passes with the suggested changes and fails with your approach, and I think it addresses both points by @mc-worker. I've added the edited LLM review summary below for the details. Appreciate it if you could review and test it @mukhanov and report back. The underlying problem is real, but the PR addresses it at the wrong level, and every run test reproduces at least one damaging behaviour:
Right fix: mc never reads data from stdin, but it reads the keyboard from stdin with ncurses, and both backends save the initial terminal modes from stdin. So the correct fix is to attach a redirected stdin to the controlling terminal once, in
Footnotes |
|
P.S. I can look into the Solaris issue when everybody is satisfied with the approach in principle. |
This fixes the issue where mc would hang on startup when stdin is not
a terminal (e.g., when run in background or in certain terminal emulators
on macOS). The program now exits with a clear error message instead of
hanging or exhibiting undefined behavior.