diff options
author | Jack Lloyd <[email protected]> | 2018-12-01 16:17:16 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-12-01 16:17:16 -0500 |
commit | 45f643a1ab837c0965f6182a62493f41bf714e68 (patch) | |
tree | c00250e5240a72be34e918c82bcef7f0ff1c97f2 /src/lib | |
parent | 1b3477faea11d501cd7705d5689fdba0281cb7e8 (diff) |
Add Win32 support for echo suppression
Tested with MinGW cross compiler and Wine.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/utils/os_utils.cpp | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp index 4c3aab476..a48e66eef 100644 --- a/src/lib/utils/os_utils.cpp +++ b/src/lib/utils/os_utils.cpp @@ -481,14 +481,14 @@ std::unique_ptr<OS::Echo_Suppression> OS::suppress_echo_on_terminal() { m_stdin_fd = fileno(stdin); if(::tcgetattr(m_stdin_fd, &m_old_termios) != 0) - throw Botan::System_Error("Getting terminal status failed", errno); + throw System_Error("Getting terminal status failed", errno); struct termios noecho_flags = m_old_termios; noecho_flags.c_lflag &= ~ECHO; noecho_flags.c_lflag |= ECHONL; if(::tcsetattr(m_stdin_fd, TCSANOW, &noecho_flags) != 0) - throw Botan::System_Error("Clearing terminal echo bit failed", errno); + throw System_Error("Clearing terminal echo bit failed", errno); } void reenable_echo() override @@ -496,7 +496,7 @@ std::unique_ptr<OS::Echo_Suppression> OS::suppress_echo_on_terminal() if(m_stdin_fd > 0) { if(::tcsetattr(m_stdin_fd, TCSANOW, &m_old_termios) != 0) - throw Botan::System_Error("Restoring terminal echo bit failed", errno); + throw System_Error("Restoring terminal echo bit failed", errno); m_stdin_fd = -1; } } @@ -518,6 +518,50 @@ std::unique_ptr<OS::Echo_Suppression> OS::suppress_echo_on_terminal() }; return std::unique_ptr<Echo_Suppression>(new POSIX_Echo_Suppression); + +#elif defined(BOTAN_TARGET_OS_HAS_WIN32) + + class Win32_Echo_Suppression : public Echo_Suppression + { + public: + Win32_Echo_Suppression() + { + m_input_handle = ::GetStdHandle(STD_INPUT_HANDLE); + if(::GetConsoleMode(m_input_handle, &m_console_state) == 0) + throw System_Error("Getting console mode failed", ::GetLastError()); + + DWORD new_mode = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; + if(::SetConsoleMode(m_input_handle, new_mode) == 0) + throw System_Error("Setting console mode failed", ::GetLastError()); + } + + void reenable_echo() override + { + if(m_input_handle != INVALID_HANDLE_VALUE) + { + if(::SetConsoleMode(m_input_handle, m_console_state) == 0) + throw System_Error("Setting console mode failed", ::GetLastError()); + m_input_handle = INVALID_HANDLE_VALUE; + } + } + + ~Win32_Echo_Suppression() + { + try + { + reenable_echo(); + } + catch(...) + { + } + } + + private: + HANDLE m_input_handle; + DWORD m_console_state; + }; + + return std::unique_ptr<Echo_Suppression>(new Win32_Echo_Suppression); #endif // Not supported on this platform, return null |