Skip to content
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

Ctrl+Break does not send 0x03 in raw mode #5128

Closed
alexrp opened this issue Mar 26, 2020 · 4 comments
Closed

Ctrl+Break does not send 0x03 in raw mode #5128

alexrp opened this issue Mar 26, 2020 · 4 comments
Labels
Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting

Comments

@alexrp
Copy link

alexrp commented Mar 26, 2020

Environment

Windows build number: Microsoft Windows [Version 10.0.19041.153]

Steps to reproduce

using System;
using System.Threading;
using Vanara.PInvoke;
using static Vanara.PInvoke.Kernel32;

namespace Test
{
    static class Program
    {
        static HandlerRoutine _handler;

        unsafe static void Main()
        {
            _handler = (e) =>
            {
                Console.WriteLine(e);
                return true;
            };

            SetConsoleCtrlHandler(_handler, true);

            var stdin = GetStdHandle(StdHandleType.STD_INPUT_HANDLE);

            GetConsoleMode(stdin, out CONSOLE_INPUT_MODE m);
            m |= CONSOLE_INPUT_MODE.ENABLE_VIRTUAL_TERMINAL_INPUT;
            m &= ~(CONSOLE_INPUT_MODE.ENABLE_PROCESSED_INPUT |
                   CONSOLE_INPUT_MODE.ENABLE_LINE_INPUT);
            SetConsoleMode(stdin, m);

            var buf = new byte[4096];

            fixed (byte* p = buf)
                Kernel32.ReadFile(stdin, (IntPtr)p, (uint)buf.Length, out _, IntPtr.Zero);

            Console.WriteLine(Win32Error.GetLastError());
            Console.WriteLine("0x{0:x2}", buf[0]);
            Thread.Sleep(2500);
        }
    }
}

Expected behavior

ERROR_SUCCESS
0x03

Actual behavior

CTRL_BREAK_EVENT
ERROR_SUCCESS
0x00

Notes

  • If the SetConsoleCtrlHandler call is removed, no output is printed at all.
  • Using ReadConsole instead makes no difference (except that ERROR_OPERATION_ABORTED is printed).
  • On Linux, if the terminal is in raw mode, both Ctrl+C and Ctrl+Break will return 0x03.
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Mar 26, 2020
@eryksun
Copy link

eryksun commented Mar 26, 2020

It's documented that "CTRL+BREAK is always treated as a signal". In HandleGenericKeyEvent Ctrl+Break is always processed to flush the input buffer, generate a control event, and terminate the read.

Is this a request to change the documented behavior to match how a raw read in Linux handles Ctrl+Break? Can you provide sample code? I tested in Linux (not WSL) using Python's tty.setraw. In raw mode, Ctrl+C is read as "\x03", but Ctrl+Break is apparently ignored.

@alexrp
Copy link
Author

alexrp commented Mar 26, 2020

Sample C code:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int main()
{
    printf("reading: ");
    fflush(stdout);

    struct termios old, new;

    tcgetattr(STDIN_FILENO, &old);
    new = old;
    cfmakeraw(&new);

    tcsetattr(STDIN_FILENO, TCSAFLUSH, &new);
    char c = 0;
    ssize_t len = read(STDIN_FILENO, &c, sizeof(c));
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &old);

    printf("0x%x\n", c);

    return 0;
}

I only have WSL2 available on this system right now; I can test on a real Linux machine later today. I tested under WSL2 with Windows Terminal and WSLtty, and interestingly the results are different: Windows Terminal gives 0x03 for Ctrl+Break while WSLtty gives 0x1c. So my initial assumption that Ctrl+C and Ctrl+Break should both produce 0x03 is almost certainly incorrect.

I'll investigate in more depth later today. Clearly this is a bit more complicated than it seemed at first. 😕

@alexrp
Copy link
Author

alexrp commented Mar 26, 2020

#1119 might be related wrt the Windows Terminal vs WSLtty discrepancy.

@alexrp
Copy link
Author

alexrp commented Mar 26, 2020

OK, well, I've tested on a number of different terminal emulators (mintty, WSLtty, Windows Terminal, PuTTY, GNOME Terminal, PowerShell, CMD, ...) on native Windows/Linux as well as WSL2, and there does not appear to be any kind of sane standard for how [Ctrl/Alt/Shift+]Break should actually work. Some terminals produce a value for those key combinations but they are all over the place (0x03, 0x1b, 0x1c, 0x1a, etc for different combinations). Some just ignore them. Some give EOF on Shift+Break. It seems like quite a mess.

So, I think it's probably safe to close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting
Projects
None yet
Development

No branches or pull requests

2 participants