Cluster
Cluster

Reputation: 1118

C#/.NET8 on Linux: read stdin char by char, not line by line (like ~ICANON mode)

I'm developing a console app for Linux using C# and .NET 8. I want to read raw data from stdin.

using (var stdin = Console.OpenStandardInput())
{
    while (true)
    {
        int b = stdin.ReadByte();
        Console.WriteLine($"Read byte: {b:X2}");
    }
}

I want to read not piped stdin data but tty. The main point is to read from terminal ANSI control codes: mouse movement, key combinations, etc. But:

  1. I'm receiving data in canonical style (ICANON mode in C): all bytes are buffered until the enter key is pressed. So it's impossible to receive input immediately. In Windows, this can be fixed using the SetConsoleMode WinAPI function. Can I use the tcsetattr Linux function in C# in some way?
  2. Arrow key presses do not work at all.

Yes, I can use Console.ReadKey(true) - it's designed for user input and it can read and parse keys immediately (somehow), and mouse capture works too. It's great for multiplatform console applications. But this function has some weird issues: key combinations like Ctrl+Space and Ctrl+2; or Ctrl+/ and Ctrl+7 share the same codes. I have no idea if it's a bug or a feature, but other Linux apps (ncurses-apps) can distinguish those keys.

So, I want to fix either stdin.ReadByte() problems or Console.ReadKey(true) problems.

Upvotes: 1

Views: 216

Answers (1)

Cluster
Cluster

Reputation: 1118

I found out that this is a Linux limitation, and there is no way to distinguish Ctrl + Space and Ctrl + 2 in the Linux console.

Upvotes: 0

Related Questions