diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/compat/stdin.cpp | 72 | ||||
-rw-r--r-- | src/compat/stdin.h | 18 |
3 files changed, 92 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 1ef62a656d..d25f7ebe87 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -520,6 +520,8 @@ endif libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ + compat/stdin.h \ + compat/stdin.cpp \ rpc/client.cpp \ $(BITCOIN_CORE_H) diff --git a/src/compat/stdin.cpp b/src/compat/stdin.cpp new file mode 100644 index 0000000000..4f2ba1e9c4 --- /dev/null +++ b/src/compat/stdin.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include <config/bitcoin-config.h> +#endif + +#include <cstdio> // for fileno(), stdin + +#ifdef WIN32 +#include <windows.h> // for SetStdinEcho() +#include <io.h> // for isatty() +#else +#include <termios.h> // for SetStdinEcho() +#include <unistd.h> // for SetStdinEcho(), isatty() +#include <sys/poll.h> // for StdinReady() +#endif + +#include <compat/stdin.h> + +// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin +void SetStdinEcho(bool enable) +{ +#ifdef WIN32 + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode; + GetConsoleMode(hStdin, &mode); + if (!enable) { + mode &= ~ENABLE_ECHO_INPUT; + } else { + mode |= ENABLE_ECHO_INPUT; + } + SetConsoleMode(hStdin, mode); +#else + struct termios tty; + tcgetattr(STDIN_FILENO, &tty); + if (!enable) { + tty.c_lflag &= ~ECHO; + } else { + tty.c_lflag |= ECHO; + } + (void)tcsetattr(STDIN_FILENO, TCSANOW, &tty); +#endif +} + +bool StdinTerminal() +{ +#ifdef WIN32 + return _isatty(_fileno(stdin)); +#else + return isatty(fileno(stdin)); +#endif +} + +bool StdinReady() +{ + if (!StdinTerminal()) { + return true; + } +#ifdef WIN32 + return false; +#else + struct pollfd fds; + fds.fd = 0; /* this is STDIN */ + fds.events = POLLIN; + return poll(&fds, 1, 0) == 1; +#endif +} + +NoechoInst::NoechoInst() { SetStdinEcho(false); } +NoechoInst::~NoechoInst() { SetStdinEcho(true); } diff --git a/src/compat/stdin.h b/src/compat/stdin.h new file mode 100644 index 0000000000..468fe4d6a6 --- /dev/null +++ b/src/compat/stdin.h @@ -0,0 +1,18 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_COMPAT_STDIN_H +#define BITCOIN_COMPAT_STDIN_H + +struct NoechoInst { + NoechoInst(); + ~NoechoInst(); +}; + +#define NO_STDIN_ECHO() NoechoInst _no_echo + +bool StdinTerminal(); +bool StdinReady(); + +#endif // BITCOIN_COMPAT_STDIN_H |