-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
System.Console.Read() needlessly changes terminal settings on linux #49129
Comments
Tagging subscribers to this area: Issue DetailsI have noticed that when using Console.Read on linux, the method disables canonical mode (ICANON) flag when reading, may apply to mac too.
|
after some investigation I cannot quite find the code responsible for the difference of behavior, but it seems like even ReadLine disables canonical mode and has it's own handling for things like backspace/etc, but ctrl+u does not work. |
cc: @tmds |
@webczat yes, .NET disables canonical mode when We can see what happens if we enable canonical mode while doing Is this something you'd want to experiment with? If not, I or someone else can take a look. The relevant code lives in https://github.com/dotnet/runtime/blob/main/src/libraries/System.Console/src/System/IO/StdInReader.cs. Look for |
mm, I found the code yesterday, just not specifically the difference between Read() and ReadLine(). |
Ah yes. I guess Windows doesn't effectively echo until there is a read call, while Linux echos as the user is typing (even when there is no read call yet). |
I didn't read enough to see whether you disable echo and manually echo yourself, or really toggle echo on ReadKey currently? it's not the ICANON flag, but similar problem. |
Independent of how you Read from Console, the configuration is: disable echo, and disable canon:
|
not sure how this can be solved, if at all, without breaking something. |
oh, they likely do for things like press any key to continue. but programs affected by terminal state when doing successive readkey may not |
how did mono handle that? or ... how does it handle that now... |
I took a look at the mono sources, I see it also disables echo and disables canonical mode. So the behavior is similar to that of .NET. |
it's actually frustrating, because that way it doesn't behave like a native linux app. Not quite sure how likely are you to create an app that depends on it, although I definitely hit one case where it made a difference that backspace didn't work, and backspace didn't work when using the |
@webczat it was an interesting discussion. Things behave the way they do to be closer to Windows behavior, which makes it less native Linux like. If you care about it for an app you're building, you can try calling I don't think we found a way to improve what .NET is doing, so I think we can close this issue? |
well the frustrating part is that it's something that would never require any action if it was not dotnet doing such things. I understand the thing about windows compat, although of course it would be nice to be able to make both sides happy here when not running on windows, if there's any way to do it that doesn't break things. |
From our discussion, the fundamental difference is that Windows delays echoing until there is a Read call, and there is no way to make Linux delay the echoing until the user calls read. The echoing already happens as the user is typing, and we can't undo it if the user calls an API that is not meant to echo.
I think this is a bug due to not proper handling runtime/src/libraries/System.Console/src/System/IO/StdInReader.cs Lines 176 to 180 in 877a8df
I will take a look at fixing this. |
wondering if it would be feasible to actually enable canon/echo when doing Read/ReadLine and disable them before ReadKey. wondering about possible racy behaviors in that case. as in the reverse of having it enabled by default and disabling on ReadKey. |
It was originally that way. But the user can be typing long before ReadKey is called. |
ehh... |
well I meant more like, disable them before readkey if changed, but don't enable them by default. although even that could pose a problem. |
When ReadKey is followed by ReadLine, characters from the line may end up not echoed. |
I have noticed that when using Console.Read on linux, the method disables canonical mode (ICANON) flag when reading, may apply to mac too.
Generally while ReadKey reads key by key and to do this it's needed to disable canonical mode and possibly echo when requested, read reads single characters, but actually blocks until newline before starting to return characters, so works similarly to scanf/cin/whatever in other languages.
However, linux itself would handle that just fine in canonical mode, so that the Read call does not have to turn it off. Turning it off makes it impossible to, for example, erase typed characters before pressing return key, or use standard terminal editing features like ctrl+u to erase line.
In canonical mode linux would start returning characters one by one, but only when the user presses enter on a terminal. Pretty sure it's standard unix behavior, and likely same for OSX.
Of course it is also an expected behavior when the program behaves like standard unix tools and just reads from standard input, if user runs it interactively, input is accepted line by line even if the program is not really doing line based input parsing. That way user still has limited edit capability but the program itself still has freedom when it goes to the way it reads input.
The text was updated successfully, but these errors were encountered: