[SOLVED] .NET runtime control over tty input and output
I am currently doing some experiments writing a console application in C#. I am trying to get a noncanonical/raw tty while using C#. Since ttys are not a C# specific concept, I followed the approach one would normally take in C: utilising
termios
to disable some tty attributes and to apply them. I am doing this by using some platform invocations to the libc
library. Setting the attributes works as expected; no errors and all the attributes I expect to be deactivated are deactivated.
Here comes the issue, however: using termios
I intentionally disabled the option the let the tty process inputs such as CTRL+C
. I would expect, then, that pressing CTRL+C
when running the binary does not stop the application; unfortunately, it does. I also disabled - again, via termios
- that input is only read line-wise. It should, instead, be read character-wise. However, input only gets read when I enter a newline character. I have tried this exact same configuration in C, where it works flawlessly.
My question then is: What additional pre-processing does the .NET runtime add to a console application and its standard I/O?
I am well aware that I can configure some of the behaviour I described earlier by setting properties on the Console
class. However, that does not give me the control I want over the tty.6 Replies
guys in allow-unsafe-block would know more but i don't think c# (or rather the clr) does really that much processing of system shortcuts like ctrl-c, i may be wrong but i believe it's more likely they are intercepted from the operating system (or an helper process) and then translated into signals/events
I would agree with this if it weren't for the fact that the same approach (calling the same functions from
termios
) works as expected when using C. Additionally, setting Console.TreatControlCAsInput
to true
does disable CTRL+C. That leads me to the assumption that this would not be something the OS is responsible for but rather the .NET runtimeTreatControlCAsInput
calls api SetConsoleMode
on windows
(but you are using linux? then it calls tcsetattr
)@Zor might know, he has been working on a library that does something similar i think?
I have this minimal example:
I use
cfmakeraw
here for ease of use; It disables the ISIG
flag which is responsible for processing the CTRL+C
keybind. However, this still cancels on CTRL+C
, which it should not.
Printing the c_lflag
also correctly shows me 101000110000
Turns out: The code does work. I just had a major flaw my approach of testing this...
Changing the Console.Readkey(true);
to a while(true) { Console.Readkey(true); }
works a lot better. CTRL+C
, of course, is a keystroke, and will end the running program... not because the interrupt gets processed, but because the program ends after a single key press...
Summary: .NET seems to behave correctly when using termios
. .NET does not seem to add any preprocessing to the I/O of a console application if configured correctly.as long as you don't touch
System.Console
or System.Diagnostics.Process
, .net will not mess with the terminal state
obligatory plug: https://github.com/vezel-dev/cathode
this library will make it fairly straightforward to work with the terminal in "raw" mode. it deals with all the platform-specific stuff and various edge cases. and also contains helpers for emitting various control sequences