aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/password.cpp47
-rw-r--r--src/common/threadpool.cpp10
-rw-r--r--src/common/util.cpp28
-rw-r--r--src/common/util.h3
4 files changed, 76 insertions, 12 deletions
diff --git a/src/common/password.cpp b/src/common/password.cpp
index b32bedae2..b3c51128f 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -56,43 +56,59 @@ namespace
bool read_from_tty(epee::wipeable_string& pass, bool hide_input)
{
- static constexpr const char BACKSPACE = 8;
-
HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE);
DWORD mode_old;
::GetConsoleMode(h_cin, &mode_old);
- DWORD mode_new = mode_old & ~((hide_input ? ENABLE_ECHO_INPUT : 0) | ENABLE_LINE_INPUT);
+ DWORD mode_new = mode_old & ~(hide_input ? ENABLE_ECHO_INPUT : 0);
::SetConsoleMode(h_cin, mode_new);
bool r = true;
pass.reserve(tools::password_container::max_password_size);
+ std::vector<int> chlen;
+ chlen.reserve(tools::password_container::max_password_size);
while (pass.size() < tools::password_container::max_password_size)
{
DWORD read;
- char ch;
- r = (TRUE == ::ReadConsoleA(h_cin, &ch, 1, &read, NULL));
+ wchar_t ucs2_ch;
+ r = (TRUE == ::ReadConsoleW(h_cin, &ucs2_ch, 1, &read, NULL));
r &= (1 == read);
+
if (!r)
{
break;
}
- else if (ch == '\n' || ch == '\r')
+ else if (ucs2_ch == L'\r')
+ {
+ continue;
+ }
+ else if (ucs2_ch == L'\n')
{
std::cout << std::endl;
break;
}
- else if (ch == BACKSPACE)
+ else if (ucs2_ch == L'\b')
{
if (!pass.empty())
{
- pass.pop_back();
+ int len = chlen.back();
+ chlen.pop_back();
+ while(len-- > 0)
+ pass.pop_back();
}
+ continue;
}
- else
- {
- pass.push_back(ch);
- }
+
+ char utf8_ch[8] = {0};
+ int len;
+ if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0)
+ break;
+
+ if(pass.size() + len >= tools::password_container::max_password_size)
+ break;
+
+ chlen.push_back(len);
+ pass += utf8_ch;
}
::SetConsoleMode(h_cin, mode_old);
@@ -146,6 +162,13 @@ namespace
if (!aPass.empty())
{
aPass.pop_back();
+ if (!hide_input)
+ std::cout << "\b\b\b \b\b\b" << std::flush;
+ }
+ else
+ {
+ if (!hide_input)
+ std::cout << "\b\b \b\b" << std::flush;
}
}
else
diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp
index 5ea04a353..37825e31d 100644
--- a/src/common/threadpool.cpp
+++ b/src/common/threadpool.cpp
@@ -51,11 +51,19 @@ threadpool::threadpool(unsigned int max_threads) : running(true), active(0) {
}
threadpool::~threadpool() {
+ try
{
const boost::unique_lock<boost::mutex> lock(mutex);
running = false;
has_work.notify_all();
}
+ catch (...)
+ {
+ // if the lock throws, we're just do it without a lock and hope,
+ // since the alternative is terminate
+ running = false;
+ has_work.notify_all();
+ }
for (size_t i = 0; i<threads.size(); i++) {
try { threads[i].join(); }
catch (...) { /* ignore */ }
@@ -91,11 +99,13 @@ unsigned int threadpool::get_max_concurrency() const {
threadpool::waiter::~waiter()
{
+ try
{
boost::unique_lock<boost::mutex> lock(mt);
if (num)
MERROR("wait should have been called before waiter dtor - waiting now");
}
+ catch (...) { /* ignore */ }
try
{
wait(NULL);
diff --git a/src/common/util.cpp b/src/common/util.cpp
index c56c77505..2a1d49af0 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -939,4 +939,32 @@ std::string get_nix_version_display_string()
}
return newval;
}
+
+#ifdef _WIN32
+ std::string input_line_win()
+ {
+ HANDLE hConIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
+ DWORD oldMode;
+
+ FlushConsoleInputBuffer(hConIn);
+ GetConsoleMode(hConIn, &oldMode);
+ SetConsoleMode(hConIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
+
+ wchar_t buffer[1024];
+ DWORD read;
+
+ ReadConsoleW(hConIn, buffer, sizeof(buffer)/sizeof(wchar_t)-1, &read, nullptr);
+ buffer[read] = 0;
+
+ SetConsoleMode(hConIn, oldMode);
+ CloseHandle(hConIn);
+
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL);
+ std::string buf(size_needed, '\0');
+ WideCharToMultiByte(CP_UTF8, 0, buffer, -1, &buf[0], size_needed, NULL, NULL);
+ buf.pop_back(); //size_needed includes null that we needed to have space for
+ return buf;
+ }
+#endif
+
}
diff --git a/src/common/util.h b/src/common/util.h
index 0e0b50520..ce773bd38 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -235,4 +235,7 @@ namespace tools
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);
std::string glob_to_regex(const std::string &val);
+#ifdef _WIN32
+ std::string input_line_win();
+#endif
}