/ src / compat / stdin.cpp
stdin.cpp
 1  // Copyright (c) 2018-2022 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  #ifdef WIN32
22      HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
23      DWORD mode;
24      GetConsoleMode(hStdin, &mode);
25      if (!enable) {
26          mode &= ~ENABLE_ECHO_INPUT;
27      } else {
28          mode |= ENABLE_ECHO_INPUT;
29      }
30      SetConsoleMode(hStdin, mode);
31  #else
32      struct termios tty;
33      tcgetattr(STDIN_FILENO, &tty);
34      if (!enable) {
35          tty.c_lflag &= ~ECHO;
36      } else {
37          tty.c_lflag |= ECHO;
38      }
39      (void)tcsetattr(STDIN_FILENO, TCSANOW, &tty);
40  #endif
41  }
42  
43  bool StdinTerminal()
44  {
45  #ifdef WIN32
46      return _isatty(_fileno(stdin));
47  #else
48      return isatty(fileno(stdin));
49  #endif
50  }
51  
52  bool StdinReady()
53  {
54      if (!StdinTerminal()) {
55          return true;
56      }
57  #ifdef WIN32
58      return false;
59  #else
60      struct pollfd fds;
61      fds.fd = STDIN_FILENO;
62      fds.events = POLLIN;
63      return poll(&fds, 1, 0) == 1;
64  #endif
65  }
66  
67  NoechoInst::NoechoInst() { SetStdinEcho(false); }
68  NoechoInst::~NoechoInst() { SetStdinEcho(true); }