aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt6
-rw-r--r--src/common/aligned.c139
-rw-r--r--src/common/aligned.h41
-rw-r--r--src/common/dns_utils.cpp18
-rw-r--r--src/common/json_util.h4
-rw-r--r--src/common/password.cpp22
-rw-r--r--src/common/password.h2
-rw-r--r--src/common/perf_timer.cpp26
-rw-r--r--src/common/perf_timer.h30
-rw-r--r--src/common/stack_trace.cpp11
-rw-r--r--src/common/updates.cpp6
-rw-r--r--src/common/util.cpp122
-rw-r--r--src/common/util.h6
13 files changed, 343 insertions, 90 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index f0df05b0d..c6bac2199 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -38,7 +38,8 @@ set(common_sources
password.cpp
perf_timer.cpp
threadpool.cpp
- updates.cpp)
+ updates.cpp
+ aligned.c)
if (STACK_TRACE)
list(APPEND common_sources stack_trace.cpp)
@@ -67,7 +68,8 @@ set(common_private_headers
perf_timer.h
stack_trace.h
threadpool.h
- updates.h)
+ updates.h
+ aligned.h)
monero_private_headers(common
${common_private_headers})
diff --git a/src/common/aligned.c b/src/common/aligned.c
new file mode 100644
index 000000000..763dfd0e7
--- /dev/null
+++ b/src/common/aligned.c
@@ -0,0 +1,139 @@
+// Copyright (c) 2017-2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include "aligned.h"
+
+static inline int is_power_of_2(size_t n) { return n && (n & (n-1)) == 0; }
+
+#define MAGIC 0xaa0817161500ff81
+#define MAGIC_FREED 0xaa0817161500ff82
+
+static void local_abort(const char *msg)
+{
+ fprintf(stderr, "%s\n", msg);
+#ifdef NDEBUG
+ _exit(1);
+#else
+ abort();
+#endif
+}
+
+typedef struct
+{
+ uint64_t magic;
+ void *raw;
+ size_t bytes;
+ size_t align;
+} control;
+
+void *aligned_malloc(size_t bytes, size_t align)
+{
+ void *raw, *ptr;
+ control *ctrl;
+
+ if (!is_power_of_2(align))
+ return NULL;
+ if (bytes > (size_t)-1 - align)
+ return NULL;
+ if (bytes + align > (size_t)-1 - sizeof(control))
+ return NULL;
+
+ raw = malloc(bytes + sizeof(control) + align);
+ if (!raw)
+ return NULL;
+ ptr = (void*)(((uintptr_t)raw + align + sizeof(control) - 1) & ~(align-1));
+ ctrl = ((control*)ptr) - 1;
+ ctrl->magic = MAGIC;
+ ctrl->raw = raw;
+ ctrl->bytes = bytes;
+ ctrl->align = align;
+ return ptr;
+}
+
+void *aligned_realloc(void *ptr, size_t bytes, size_t align)
+{
+ void *raw, *ptr2;
+ control *ctrl, *ctrl2;
+
+ if (!ptr)
+ return aligned_malloc(bytes, align);
+ if (!bytes)
+ {
+ aligned_free(ptr);
+ return NULL;
+ }
+ if (!is_power_of_2(align))
+ return NULL;
+
+ ctrl = ((control*)ptr) - 1;
+ if (ctrl->magic == MAGIC_FREED)
+ local_abort("Double free detected");
+ if (ctrl->magic != MAGIC)
+ local_abort("Freeing unallocated memory");
+ if (ctrl->align != align)
+ return NULL;
+ if (ctrl->bytes >= bytes)
+ return ptr;
+
+ if (ctrl->bytes > (size_t)-1 - ctrl->align)
+ return NULL;
+ if (ctrl->bytes + ctrl->align > (size_t)-1 - sizeof(control))
+ return NULL;
+
+ raw = malloc(bytes + sizeof(control) + ctrl->align);
+ if (!raw)
+ return NULL;
+ ptr2 = (void*)(((uintptr_t)raw + ctrl->align + sizeof(control) - 1) & ~(ctrl->align-1));
+ memcpy(ptr2, ptr, ctrl->bytes);
+ ctrl2 = ((control*)ptr2) - 1;
+ ctrl2->magic = MAGIC;
+ ctrl2->raw = raw;
+ ctrl2->bytes = bytes;
+ ctrl2->align = ctrl->align;
+ ctrl->magic = MAGIC_FREED;
+ free(ctrl->raw);
+ return ptr2;
+}
+
+void aligned_free(void *ptr)
+{
+ if (!ptr)
+ return;
+ control *ctrl = ((control*)ptr) - 1;
+ if (ctrl->magic == MAGIC_FREED)
+ local_abort("Double free detected");
+ if (ctrl->magic != MAGIC)
+ local_abort("Freeing unallocated memory");
+ ctrl->magic = MAGIC_FREED;
+ free(ctrl->raw);
+}
diff --git a/src/common/aligned.h b/src/common/aligned.h
new file mode 100644
index 000000000..fed3ccb36
--- /dev/null
+++ b/src/common/aligned.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *aligned_malloc(size_t bytes, size_t align);
+void *aligned_realloc(void *ptr, size_t bytes, size_t align);
+void aligned_free(void *ptr);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 33f60bc3c..3f2bde620 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -97,11 +97,16 @@ get_builtin_cert(void)
*/
/** return the built in root DS trust anchor */
-static const char*
+static const char* const*
get_builtin_ds(void)
{
- return
-". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n";
+ static const char * const ds[] =
+ {
+ ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n",
+ ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n",
+ NULL
+ };
+ return ds;
}
/************************************************************
@@ -240,7 +245,12 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData())
ub_ctx_hosts(m_data->m_ub_context, NULL);
}
- ub_ctx_add_ta(m_data->m_ub_context, string_copy(::get_builtin_ds()));
+ const char * const *ds = ::get_builtin_ds();
+ while (*ds)
+ {
+ MINFO("adding trust anchor: " << *ds);
+ ub_ctx_add_ta(m_data->m_ub_context, string_copy(*ds++));
+ }
}
DNSResolver::~DNSResolver()
diff --git a/src/common/json_util.h b/src/common/json_util.h
index 661022a6f..c320c3956 100644
--- a/src/common/json_util.h
+++ b/src/common/json_util.h
@@ -29,14 +29,14 @@
#pragma once
#define GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, name, type, jtype, mandatory, def) \
- type field_##name = def; \
+ type field_##name = static_cast<type>(def); \
bool field_##name##_found = false; \
(void)field_##name##_found; \
do if (json.HasMember(#name)) \
{ \
if (json[#name].Is##jtype()) \
{ \
- field_##name = json[#name].Get##jtype(); \
+ field_##name = static_cast<type>(json[#name].Get##jtype()); \
field_##name##_found = true; \
} \
else \
diff --git a/src/common/password.cpp b/src/common/password.cpp
index 3ce2ba42a..5671c4a4e 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -54,7 +54,7 @@ namespace
return 0 != _isatty(_fileno(stdin));
}
- bool read_from_tty(epee::wipeable_string& pass)
+ bool read_from_tty(epee::wipeable_string& pass, bool hide_input)
{
static constexpr const char BACKSPACE = 8;
@@ -62,7 +62,7 @@ namespace
DWORD mode_old;
::GetConsoleMode(h_cin, &mode_old);
- DWORD mode_new = mode_old & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
+ DWORD mode_new = mode_old & ~((hide_input ? ENABLE_ECHO_INPUT : 0) | ENABLE_LINE_INPUT);
::SetConsoleMode(h_cin, mode_new);
bool r = true;
@@ -107,14 +107,14 @@ namespace
return 0 != isatty(fileno(stdin));
}
- int getch() noexcept
+ int getch(bool hide_input) noexcept
{
struct termios tty_old;
tcgetattr(STDIN_FILENO, &tty_old);
struct termios tty_new;
tty_new = tty_old;
- tty_new.c_lflag &= ~(ICANON | ECHO);
+ tty_new.c_lflag &= ~(ICANON | (hide_input ? ECHO : 0));
tcsetattr(STDIN_FILENO, TCSANOW, &tty_new);
int ch = getchar();
@@ -124,14 +124,14 @@ namespace
return ch;
}
- bool read_from_tty(epee::wipeable_string& aPass)
+ bool read_from_tty(epee::wipeable_string& aPass, bool hide_input)
{
static constexpr const char BACKSPACE = 127;
aPass.reserve(tools::password_container::max_password_size);
while (aPass.size() < tools::password_container::max_password_size)
{
- int ch = getch();
+ int ch = getch(hide_input);
if (EOF == ch || ch == EOT)
{
return false;
@@ -159,18 +159,18 @@ namespace
#endif // end !WIN32
- bool read_from_tty(const bool verify, const char *message, epee::wipeable_string& pass1, epee::wipeable_string& pass2)
+ bool read_from_tty(const bool verify, const char *message, bool hide_input, epee::wipeable_string& pass1, epee::wipeable_string& pass2)
{
while (true)
{
if (message)
std::cout << message <<": " << std::flush;
- if (!read_from_tty(pass1))
+ if (!read_from_tty(pass1, hide_input))
return false;
if (verify)
{
std::cout << "Confirm password: ";
- if (!read_from_tty(pass2))
+ if (!read_from_tty(pass2, hide_input))
return false;
if(pass1!=pass2)
{
@@ -229,12 +229,12 @@ namespace tools
std::atomic<bool> password_container::is_prompting(false);
- boost::optional<password_container> password_container::prompt(const bool verify, const char *message)
+ boost::optional<password_container> password_container::prompt(const bool verify, const char *message, bool hide_input)
{
is_prompting = true;
password_container pass1{};
password_container pass2{};
- if (is_cin_tty() ? read_from_tty(verify, message, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password))
+ if (is_cin_tty() ? read_from_tty(verify, message, hide_input, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password))
{
is_prompting = false;
return {std::move(pass1)};
diff --git a/src/common/password.h b/src/common/password.h
index 61937b93a..529881e40 100644
--- a/src/common/password.h
+++ b/src/common/password.h
@@ -49,7 +49,7 @@ namespace tools
password_container(std::string&& password) noexcept;
//! \return A password from stdin TTY prompt or `std::cin` pipe.
- static boost::optional<password_container> prompt(bool verify, const char *mesage = "Password");
+ static boost::optional<password_container> prompt(bool verify, const char *mesage = "Password", bool hide_input = true);
static std::atomic<bool> is_prompting;
password_container(const password_container&) = delete;
diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp
index 16abdfd99..6910ebdd4 100644
--- a/src/common/perf_timer.cpp
+++ b/src/common/perf_timer.cpp
@@ -33,7 +33,7 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "perf"
-namespace
+namespace tools
{
uint64_t get_tick_count()
{
@@ -83,7 +83,7 @@ namespace tools
el::Level performance_timer_log_level = el::Level::Debug;
-static __thread std::vector<PerformanceTimer*> *performance_timers = NULL;
+static __thread std::vector<LoggingPerformanceTimer*> *performance_timers = NULL;
void set_performance_timer_log_level(el::Level level)
{
@@ -96,17 +96,24 @@ void set_performance_timer_log_level(el::Level level)
performance_timer_log_level = level;
}
-PerformanceTimer::PerformanceTimer(const std::string &s, uint64_t unit, el::Level l): name(s), unit(unit), level(l), started(false), paused(false)
+PerformanceTimer::PerformanceTimer(bool paused): started(true), paused(paused)
+{
+ if (paused)
+ ticks = 0;
+ else
+ ticks = get_tick_count();
+}
+
+LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, uint64_t unit, el::Level l): PerformanceTimer(), name(s), unit(unit), level(l)
{
- ticks = get_tick_count();
if (!performance_timers)
{
MLOG(level, "PERF ----------");
- performance_timers = new std::vector<PerformanceTimer*>();
+ performance_timers = new std::vector<LoggingPerformanceTimer*>();
}
else
{
- PerformanceTimer *pt = performance_timers->back();
+ LoggingPerformanceTimer *pt = performance_timers->back();
if (!pt->started && !pt->paused)
{
size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size;
@@ -119,9 +126,14 @@ PerformanceTimer::PerformanceTimer(const std::string &s, uint64_t unit, el::Leve
PerformanceTimer::~PerformanceTimer()
{
- performance_timers->pop_back();
if (!paused)
ticks = get_tick_count() - ticks;
+}
+
+LoggingPerformanceTimer::~LoggingPerformanceTimer()
+{
+ pause();
+ performance_timers->pop_back();
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;
diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h
index 0e910caf9..675d6234d 100644
--- a/src/common/perf_timer.h
+++ b/src/common/perf_timer.h
@@ -43,30 +43,46 @@ class PerformanceTimer;
extern el::Level performance_timer_log_level;
+uint64_t get_tick_count();
+uint64_t get_ticks_per_ns();
+uint64_t ticks_to_ns(uint64_t ticks);
+
class PerformanceTimer
{
public:
- PerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug);
+ PerformanceTimer(bool paused = false);
~PerformanceTimer();
void pause();
void resume();
+ uint64_t value() const { return ticks; }
+void set(uint64_t v){ticks=v;}
+
+protected:
+ uint64_t ticks;
+ bool started;
+ bool paused;
+};
+
+class LoggingPerformanceTimer: public PerformanceTimer
+{
+public:
+ LoggingPerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug);
+ ~LoggingPerformanceTimer();
+
private:
std::string name;
uint64_t unit;
el::Level level;
- uint64_t ticks;
- bool started;
- bool paused;
};
void set_performance_timer_log_level(el::Level level);
-#define PERF_TIMER_UNIT(name, unit) tools::PerformanceTimer pt_##name(#name, unit, tools::performance_timer_log_level)
-#define PERF_TIMER_UNIT_L(name, unit, l) tools::PerformanceTimer pt_##name(#name, unit, l)
+#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::PerformanceTimer> pt_##name(new tools::PerformanceTimer(#name, unit, el::Level::Info))
+#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_STOP(name) do { pt_##name.reset(NULL); } while(0)
#define PERF_TIMER_PAUSE(name) pt_##name->pause()
diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp
index d6dc4d7cc..141621427 100644
--- a/src/common/stack_trace.cpp
+++ b/src/common/stack_trace.cpp
@@ -49,7 +49,16 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "stacktrace"
-#define ST_LOG(x) CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x
+#define ST_LOG(x) \
+ do { \
+ auto elpp = ELPP; \
+ if (elpp) { \
+ CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x; \
+ } \
+ else { \
+ std::cout << x << std::endl; \
+ } \
+ } while(0)
// from https://stackoverflow.com/questions/11665829/how-can-i-print-stack-trace-for-caught-exceptions-in-c-code-injection-in-c
diff --git a/src/common/updates.cpp b/src/common/updates.cpp
index 9eb402e0b..9f12f8dbc 100644
--- a/src/common/updates.cpp
+++ b/src/common/updates.cpp
@@ -69,12 +69,12 @@ namespace tools
continue;
bool alnum = true;
- for (auto c: hash)
+ for (auto c: fields[3])
if (!isalnum(c))
alnum = false;
- if (hash.size() != 64 && !alnum)
+ if (fields[3].size() != 64 && !alnum)
{
- MWARNING("Invalid hash: " << hash);
+ MWARNING("Invalid hash: " << fields[3]);
continue;
}
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 7d9d7b408..c56c77505 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -37,7 +37,7 @@
#ifdef __GLIBC__
#include <sys/types.h>
#include <sys/stat.h>
-#include <ustat.h>
+#include <sys/resource.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
@@ -45,6 +45,13 @@
#include <string>
#endif
+//tools::is_hdd
+#ifdef __GLIBC__
+ #include <sstream>
+ #include <sys/sysmacros.h>
+ #include <fstream>
+#endif
+
#include "unbound.h"
#include "include_base_utils.h"
@@ -682,6 +689,21 @@ std::string get_nix_version_display_string()
static void setup_crash_dump() {}
#endif
+ bool disable_core_dumps()
+ {
+#ifdef __GLIBC__
+ // disable core dumps in release mode
+ struct rlimit rlimit;
+ rlimit.rlim_cur = rlimit.rlim_max = 0;
+ if (setrlimit(RLIMIT_CORE, &rlimit))
+ {
+ MWARNING("Failed to disable core dumps");
+ return false;
+ }
+#endif
+ return true;
+ }
+
bool on_startup()
{
mlog_configure("", true);
@@ -717,62 +739,41 @@ std::string get_nix_version_display_string()
#endif
}
- bool is_hdd(const char *path)
+ boost::optional<bool> is_hdd(const char *file_path)
{
#ifdef __GLIBC__
- std::string device = "";
- struct stat st, dst;
- if (stat(path, &st) < 0)
- return 0;
-
- DIR *dir = opendir("/dev/block");
- if (!dir)
- return 0;
- struct dirent *de;
- while ((de = readdir(dir)))
- {
- if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
+ struct stat st;
+ std::string prefix;
+ if(stat(file_path, &st) == 0)
+ {
+ std::ostringstream s;
+ s << "/sys/dev/block/" << major(st.st_dev) << ":" << minor(st.st_dev);
+ prefix = s.str();
+ }
+ else
+ {
+ return boost::none;
+ }
+ std::string attr_path = prefix + "/queue/rotational";
+ std::ifstream f(attr_path, std::ios_base::in);
+ if(not f.is_open())
+ {
+ attr_path = prefix + "/../queue/rotational";
+ f.open(attr_path, std::ios_base::in);
+ if(not f.is_open())
{
- std::string dev_path = std::string("/dev/block/") + de->d_name;
- char resolved[PATH_MAX];
- if (realpath(dev_path.c_str(), resolved) && !strncmp(resolved, "/dev/", 5))
- {
- if (stat(resolved, &dst) == 0)
- {
- if (dst.st_rdev == st.st_dev)
- {
- // take out trailing digits (eg, sda1 -> sda)
- char *ptr = resolved;
- while (*ptr)
- ++ptr;
- while (ptr > resolved && isdigit(*--ptr))
- *ptr = 0;
- device = resolved + 5;
- break;
- }
- }
- }
+ return boost::none;
}
}
- closedir(dir);
-
- if (device.empty())
- return 0;
-
- std::string sys_path = "/sys/block/" + device + "/queue/rotational";
- FILE *f = fopen(sys_path.c_str(), "r");
- if (!f)
- return false;
- char s[8];
- char *ptr = fgets(s, sizeof(s), f);
- fclose(f);
- if (!ptr)
- return 0;
- s[sizeof(s) - 1] = 0;
- int n = atoi(s); // returns 0 on parse error
- return n == 1;
+ unsigned short val = 0xdead;
+ f >> val;
+ if(not f.fail())
+ {
+ return (val == 1);
+ }
+ return boost::none;
#else
- return 0;
+ return boost::none;
#endif
}
@@ -919,4 +920,23 @@ std::string get_nix_version_display_string()
return {};
}
}
+
+ std::string glob_to_regex(const std::string &val)
+ {
+ std::string newval;
+
+ bool escape = false;
+ for (char c: val)
+ {
+ if (c == '*')
+ newval += escape ? "*" : ".*";
+ else if (c == '?')
+ newval += escape ? "?" : ".";
+ else if (c == '\\')
+ newval += '\\', escape = !escape;
+ else
+ newval += c;
+ }
+ return newval;
+ }
}
diff --git a/src/common/util.h b/src/common/util.h
index a57a85fee..0e0b50520 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -149,6 +149,8 @@ namespace tools
bool sanitize_locale();
+ bool disable_core_dumps();
+
bool on_startup();
/*! \brief Defines a signal handler for win32 and *nix
@@ -228,7 +230,9 @@ namespace tools
bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash);
bool sha256sum(const std::string &filename, crypto::hash &hash);
- bool is_hdd(const char *path);
+ boost::optional<bool> is_hdd(const char *path);
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);
+
+ std::string glob_to_regex(const std::string &val);
}