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 |
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 is a good point; all I could find in the standard is this: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stdin.html So, apparently, at least when the program starts, https://lists.rtems.org/pipermail/users/2011-March/023277.html So the rule can probably be formulated like this: "if you haven't done anything on the descriptors yet, you can use I think that in theory, we could change all usages of My guess is that the previous policy was to use one or the other "as appropriate" as one "know what one's doing", and later, probably just copying what the last used one pattern was. In this case, I and the LLM simply followed the current usage patterns without evaluating whether this is right or wrong. To my mind, the best style would be to use each "as appropriate", but I guess this is not achievable, since for that one has to understand what rebinds which descriptors where, how and why globally. Therefore, I wouldn't object to you applying a radical solution moving everything to |
Okay, this is very useful to know, thank you. In this case, I guess, we can decide on the mechanical migration to |
|
@zyv I have reviewed and tested the alternative patch series (fe3b6e1) on macOS/arm64, both S-Lang and ncurses builds. All 70 unit tests pass on each backend, including the new Three minor notes: (1) |
zyv
left a comment
There was a problem hiding this comment.
@mukhanov thanks for your notes and testing! I've finally gotten around to fixing the remaining issues. The Solaris issue was a test problem, and the rest of the notes should also be addressed now just for completeness. I've also fixed the outdated comment while I was at it.
|
care to push a re-cut, yury? i'd review this from scratch, so the current state is not helpful. |
|
/rebase |
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 the only terminal is a write-only stderr or there is no terminal at all. On System V systems, the pseudo-terminal is not a terminal until the ptem and ldterm STREAMS modules are pushed onto it, unless they are autopushed. Open it before setsid(), because on illumos pushing them in a session leader makes it the controlling terminal even with O_NOCTTY. Acquire the controlling terminal by opening it without O_NOCTTY first, and with TIOCSCTTY only if that did not work, because on illumos (and likely on Solaris) TIOCSCTTY fails if the terminal already is the controlling one. 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>
Also fix the comment in tty_change_screen_size(), which has referred to stdin since the ioctl() was switched to stdout in ea2c57d. Assisted-By: Claude Opus 5.5 Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
9c7c485 to
6f03713
Compare
ossilator
left a comment
There was a problem hiding this comment.
commit 1: the wording "attach redirected stdin" is just weird. it's also kinda imprecise, as one could redirect from another tty. the summary should be more like "ensure that stdin is a tty", and the complementary phrase "when stdin is not a tty [due to having been redirected]".
the speculation about future direction should stay.
commit 2 should be arguably squashed into commit 1 (in most projects, committing the fix and its regression test together is preferred/required).
in either case its commit message is excessive due to being redundant with the code comments (also, the commit message should only answer what+why, while the how belongs into comments).
why/where would you squash commit 3? it seems semantically separate to me.
it would be nice to pull commit 4 ahead to have a cleaner baseline, but that would require resolving merge conflicts.
commit 5's description should point out how this differs from other targets, implicitly answering why they don't need adjustment.
| return FALSE; | ||
| } | ||
|
|
||
| return isatty (STDIN_FILENO) != 0; |
There was a problem hiding this comment.
that check makes no sense at this point.
| { | ||
| mc_propagate_error (&mcerror, 0, "%s", | ||
| _ ("Standard input is not a terminal and there is no controlling " | ||
| "terminal to read the keyboard from")); |
There was a problem hiding this comment.
use "keyboard input" rather than just "keyboard" (also in the commit message and comment above).
| // given: stdin is a terminal | ||
|
|
||
| // when | ||
| const int actual_result = run_stdin_to_terminal (STDIN_IS_TTY); |
There was a problem hiding this comment.
doesn't the framework provide a way to do table-driven testing? the duplication of the bodies isn't very elegant.
| // disable SIGQUIT to allow use Ctrl-\ key | ||
| mode.c_cc[VQUIT] = NULL_VALUE; | ||
| tcsetattr (STDIN_FILENO, TCSANOW, &mode); | ||
| // don't apply an uninitialized structure if the terminal modes cannot be read |
There was a problem hiding this comment.
that's a rather pointless comment, because it's stating the obvious.
more interesting questions would be why it's bad if that happens and why it's ok to just skip over it. by extension this means pointing out why it would fail in the first place.
287b444 to
6f172fd
Compare
Builds run inside a VM, and workspace files are not available to the artifact upload step upon failure under the default sync strategy (rsync on success only). Switch to the nfs strategy establishing a live bidirectional workspace bridge between the host and the VM. Made possible by vmactions/solaris-vm#70. Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
6f172fd to
3d268ad
Compare
Oh, this is a long and painful story to tell. The sort of stuff most people use without willing to understand how it works, and then the tool sucks, obviously. As I was setting up the CI during my full-time mc work streak, I found that the best way to test on "exotic" systems that are not directly supported by GitHub Actions is the vmactions system, running them in QEMU. Most Linux distributions are "easily" testable in Docker on top of the normal Actions runners, but not BSD or Solaris. The problem is that Docker shares the workspace with the runner, but QEMU is a completely separate machine, and the workspace is synced with rsync. Back then, there were no other possibilities as far as I remember, so if the build fails, the only possibility to peek into the VM was to print more. Now, the author introduced NFS-backed shared workspaces, so in theory, even if the run fails, the changes are mirrored in the workspace. I tried it, and it wasn't working correctly on Solaris, even though it kind of worked on BSD. Luckily, the author is very responsive and has already fixed it in vmactions/solaris-vm#70. I've moved this to #5193. |
|
ok, i'd prepend something along the lines of "unlike the linux builds which are docker-based, the bsd and solaris builds have to use proper vms. unfortunately, ..." pedantically, that commit also doesn't belong into this PR, but into a separate one (that would be merged first). it doesn't matter at the commit level, but the project policy is to use --no-ff, so correct logical grouping is preferable. |
To my mind, that's below the threshold of assumed knowledge for someone editing GitHub Actions workflows. The commit now says what makes these workflows different, and I wouldn't want to add more explanations as to how the rest of the system works and why. Besides, this is incorrect - the Linux builds are not Docker-based per se, and macOS/Windows builds are handled in a different fashion but natively.
I've already replied earlier that I've moved it to a different branch. I didn't force-push here as I didn't get to the rest of the comments. |
|
Hi @zyv, thanks again for working through this! I see that the remaining review comments are being addressed. Happy to help with any of them or re-test the updated patch series on macOS (both S-Lang and ncurses) once it's ready. Just let me know if there's anything you'd like me to take care of. |
it certainly is, but you shouldn't assume such a specialized audience. providing some minimal context for newcomers and downstreams is worthwhile, even beyond the review phase.
no, you said you moved it to an issue. with no visible artifacts, i was a bit confused. when you withhold work for practical reasons, it makes sense to be a tiny bit more verbose, say "already moved it to #...'s branch locally". |
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.