stdin.cpp
1 // Copyright (c) 2018-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <compat/stdin.h> 6 7 #include <cstdio> 8 9 #ifdef WIN32 10 #include <windows.h> 11 #include <io.h> 12 #else 13 #include <termios.h> 14 #include <unistd.h> 15 #include <poll.h> 16 #endif 17 18 // https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin 19 void SetStdinEcho(bool enable) 20 { 21 if (!StdinTerminal()) { 22 return; 23 } 24 #ifdef WIN32 25 HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 26 DWORD mode; 27 if (!GetConsoleMode(hStdin, &mode)) { 28 fputs("GetConsoleMode failed\n", stderr); 29 return; 30 } 31 if (!enable) { 32 mode &= ~ENABLE_ECHO_INPUT; 33 } else { 34 mode |= ENABLE_ECHO_INPUT; 35 } 36 if (!SetConsoleMode(hStdin, mode)) { 37 fputs("SetConsoleMode failed\n", stderr); 38 } 39 #else 40 struct termios tty; 41 if (tcgetattr(STDIN_FILENO, &tty) != 0) { 42 fputs("tcgetattr failed\n", stderr); 43 return; 44 } 45 if (!enable) { 46 tty.c_lflag &= static_cast<decltype(tty.c_lflag)>(~ECHO); 47 } else { 48 tty.c_lflag |= ECHO; 49 } 50 if (tcsetattr(STDIN_FILENO, TCSANOW, &tty) != 0) { 51 fputs("tcsetattr failed\n", stderr); 52 } 53 #endif 54 } 55 56 bool StdinTerminal() 57 { 58 #ifdef WIN32 59 return _isatty(_fileno(stdin)); 60 #else 61 return isatty(fileno(stdin)); 62 #endif 63 } 64 65 bool StdinReady() 66 { 67 if (!StdinTerminal()) { 68 return true; 69 } 70 #ifdef WIN32 71 return false; 72 #else 73 struct pollfd fds; 74 fds.fd = STDIN_FILENO; 75 fds.events = POLLIN; 76 return poll(&fds, 1, 0) == 1; 77 #endif 78 } 79 80 NoechoInst::NoechoInst() { SetStdinEcho(false); } 81 NoechoInst::~NoechoInst() { SetStdinEcho(true); }