aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/expect.h4
-rw-r--r--src/common/password.cpp47
-rw-r--r--src/common/perf_timer.cpp8
-rw-r--r--src/common/perf_timer.h18
-rw-r--r--src/common/spawn.cpp3
-rw-r--r--src/common/threadpool.cpp10
-rw-r--r--src/common/util.cpp75
-rw-r--r--src/common/util.h5
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);
}