diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index 80ad7ecf9..10c53ddb9 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -24,6 +24,9 @@ #include #include #include "Exceptions.h" +#ifndef _WIN32 +#include +#endif using namespace std; using namespace dev; @@ -126,6 +129,29 @@ std::string dev::getPassword(std::string const& _prompt) std::getline(cin, ret); return ret; #else - return getpass(_prompt.c_str()); + struct termios oflags; + struct termios nflags; + char password[128]; + + // disable echo in the terminal + tcgetattr(fileno(stdin), &oflags); + nflags = oflags; + nflags.c_lflag &= ~ECHO; + nflags.c_lflag |= ECHONL; + + if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr")); + + printf("%s", _prompt.c_str()); + if (!fgets(password, sizeof(password), stdin)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets")); + password[strlen(password) - 1] = 0; + + // restore terminal + if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) { + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr")); + } + + return password; #endif } diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 36c624a71..025568efa 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -54,6 +54,7 @@ struct FileError: virtual Exception {}; struct Overflow: virtual Exception {}; struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; struct FailedInvariant: virtual Exception {}; +struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} }; // error information to be added to exceptions using errinfo_invalidSymbol = boost::error_info;