diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/expect.h | 4 | ||||
-rw-r--r-- | src/common/password.cpp | 47 | ||||
-rw-r--r-- | src/common/perf_timer.cpp | 8 | ||||
-rw-r--r-- | src/common/perf_timer.h | 18 | ||||
-rw-r--r-- | src/common/spawn.cpp | 3 | ||||
-rw-r--r-- | src/common/threadpool.cpp | 10 | ||||
-rw-r--r-- | src/common/util.cpp | 75 | ||||
-rw-r--r-- | src/common/util.h | 5 |
8 files changed, 141 insertions, 29 deletions
diff --git a/src/common/expect.h b/src/common/expect.h index 326242502..72e4060a7 100644 --- a/src/common/expect.h +++ b/src/common/expect.h @@ -350,7 +350,9 @@ public: using error_type = std::error_code; //! Create a successful object. - expect() = default; + expect() noexcept + : code_() + {} expect(std::error_code const& code) noexcept : code_(code) 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/perf_timer.cpp b/src/common/perf_timer.cpp index 6910ebdd4..47f01de65 100644 --- a/src/common/perf_timer.cpp +++ b/src/common/perf_timer.cpp @@ -104,11 +104,11 @@ PerformanceTimer::PerformanceTimer(bool paused): started(true), paused(paused) ticks = get_tick_count(); } -LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, uint64_t unit, el::Level l): PerformanceTimer(), name(s), unit(unit), level(l) +LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l): PerformanceTimer(), name(s), cat(cat), unit(unit), level(l) { if (!performance_timers) { - MLOG(level, "PERF ----------"); + MCLOG(level, cat.c_str(), "PERF ----------"); performance_timers = new std::vector<LoggingPerformanceTimer*>(); } else @@ -117,7 +117,7 @@ LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, uint64_t if (!pt->started && !pt->paused) { size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size; - MLOG(pt->level, "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); + MCLOG(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); pt->started = true; } } @@ -137,7 +137,7 @@ LoggingPerformanceTimer::~LoggingPerformanceTimer() char s[12]; snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit))); size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size; - MLOG(level, "PERF " << s << std::string(size * 2, ' ') << " " << name); + MCLOG(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name); if (performance_timers->empty()) { delete performance_timers; diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h index 675d6234d..1d4dee5b5 100644 --- a/src/common/perf_timer.h +++ b/src/common/perf_timer.h @@ -33,9 +33,6 @@ #include <memory> #include "misc_log_ex.h" -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "perf" - namespace tools { @@ -67,23 +64,24 @@ protected: class LoggingPerformanceTimer: public PerformanceTimer { public: - LoggingPerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug); + LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l = el::Level::Debug); ~LoggingPerformanceTimer(); private: std::string name; + std::string cat; uint64_t unit; el::Level level; }; void set_performance_timer_log_level(el::Level level); -#define PERF_TIMER_UNIT(name, unit) tools::LoggingPerformanceTimer pt_##name(#name, unit, tools::performance_timer_log_level) -#define PERF_TIMER_UNIT_L(name, unit, l) tools::LoggingPerformanceTimer pt_##name(#name, unit, l) -#define PERF_TIMER(name) PERF_TIMER_UNIT(name, 1000) -#define PERF_TIMER_L(name, l) PERF_TIMER_UNIT_L(name, 1000, l) -#define PERF_TIMER_START_UNIT(name, unit) std::unique_ptr<tools::LoggingPerformanceTimer> pt_##name(new tools::LoggingPerformanceTimer(#name, unit, el::Level::Info)) -#define PERF_TIMER_START(name) PERF_TIMER_START_UNIT(name, 1000) +#define PERF_TIMER_UNIT(name, unit) tools::LoggingPerformanceTimer pt_##name(#name, "perf." MONERO_DEFAULT_LOG_CATEGORY, unit, tools::performance_timer_log_level) +#define PERF_TIMER_UNIT_L(name, unit, l) tools::LoggingPerformanceTimer pt_##name(#name, "perf." MONERO_DEFAULT_LOG_CATEGORY, unit, l) +#define PERF_TIMER(name) PERF_TIMER_UNIT(name, 1000000) +#define PERF_TIMER_L(name, l) PERF_TIMER_UNIT_L(name, 1000000, l) +#define PERF_TIMER_START_UNIT(name, unit) std::unique_ptr<tools::LoggingPerformanceTimer> pt_##name(new tools::LoggingPerformanceTimer(#name, "perf." MONERO_DEFAULT_LOG_CATEGORY, unit, el::Level::Info)) +#define PERF_TIMER_START(name) PERF_TIMER_START_UNIT(name, 1000000) #define PERF_TIMER_STOP(name) do { pt_##name.reset(NULL); } while(0) #define PERF_TIMER_PAUSE(name) pt_##name->pause() #define PERF_TIMER_RESUME(name) pt_##name->resume() diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp index 59f11675c..0a2ce8387 100644 --- a/src/common/spawn.cpp +++ b/src/common/spawn.cpp @@ -38,6 +38,7 @@ #endif #include "misc_log_ex.h" +#include "util.h" #include "spawn.h" namespace tools @@ -101,6 +102,8 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait) // child if (pid == 0) { + tools::closefrom(3); + close(0); char *envp[] = {NULL}; execve(filename, argv, envp); MERROR("Failed to execve: " << strerror(errno)); 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..43973c511 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -28,6 +28,7 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include <unistd.h> #include <cstdio> #ifdef __GLIBC__ @@ -233,7 +234,7 @@ namespace tools MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category())); } #else - m_fd = open(filename.c_str(), O_RDONLY | O_CREAT, 0666); + m_fd = open(filename.c_str(), O_RDONLY | O_CREAT | O_CLOEXEC, 0666); if (m_fd != -1) { if (flock(m_fd, LOCK_EX | LOCK_NB) == -1) @@ -307,10 +308,19 @@ namespace tools StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft ")); // Test for the specific product. + if ( osvi.dwMajorVersion == 10 ) + { + if ( osvi.dwMinorVersion == 0 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + StringCchCat(pszOS, BUFSIZE, TEXT("Windows 10 ")); + else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2016 " )); + } + } if ( osvi.dwMajorVersion == 6 ) { - if( osvi.dwMinorVersion == 0 ) + if ( osvi.dwMinorVersion == 0 ) { if( osvi.wProductType == VER_NT_WORKSTATION ) StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista ")); @@ -324,6 +334,20 @@ namespace tools else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 " )); } + if ( osvi.dwMinorVersion == 2 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + StringCchCat(pszOS, BUFSIZE, TEXT("Windows 8 ")); + else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2012 " )); + } + + if ( osvi.dwMinorVersion == 3 ) + { + if( osvi.wProductType == VER_NT_WORKSTATION ) + StringCchCat(pszOS, BUFSIZE, TEXT("Windows 8.1 ")); + else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2012 R2 " )); + } + pGPI = (PGPI) GetProcAddress( GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); @@ -939,4 +963,51 @@ 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 + + void closefrom(int fd) + { +#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__ + ::closefrom(fd); +#else +#if defined __GLIBC__ + const int sc_open_max = sysconf(_SC_OPEN_MAX); + const int MAX_FDS = std::min(65536, sc_open_max); +#else + const int MAX_FDS = 65536; +#endif + while (fd < MAX_FDS) + { + close(fd); + ++fd; + } +#endif + } + } diff --git a/src/common/util.h b/src/common/util.h index 0e0b50520..e793a42b5 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -235,4 +235,9 @@ 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 + + void closefrom(int fd); } |