summaryrefslogtreecommitdiffhomepage
path: root/os.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'os.cpp')
-rw-r--r--os.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/os.cpp b/os.cpp
new file mode 100644
index 0000000..10bf1c1
--- /dev/null
+++ b/os.cpp
@@ -0,0 +1,78 @@
+#include "os.h"
+
+#include <boost/algorithm/string/split.hpp>
+
+#include <unistd.h>
+
+#include <fstream>
+#include <vector>
+
+using namespace std::string_literals;
+
+namespace {
+
+ std::string to_string(uint32_t v, size_t size)
+ {
+ std::string result{std::to_string(v)};
+
+ return (size > result.size() ? std::string(size - result.size(), char('0')) : ""s) + result;
+ }
+
+ std::string to_time_string(uint32_t sec)
+ {
+ uint32_t days = sec / (24 * 3600);
+ uint32_t hours = (sec % (24 * 3600)) / 3600;
+ uint32_t minutes = (sec % 3600) / 60;
+ uint32_t seconds = (sec % 60);
+
+ return std::to_string(days) + " days, "s + to_string(hours, 2) + ":"s + to_string(minutes, 2) + ":"s + to_string(seconds, 2);
+ }
+
+ uint64_t uptime()
+ {
+ double uptime_seconds{};
+ if (std::ifstream("/proc/uptime", std::ios::in) >> uptime_seconds)
+ {
+ return static_cast<uint64_t>(uptime_seconds);
+ }
+
+ return 0;
+ }
+
+} // anonymous namespace
+
+std::string OS::uptime_host()
+{
+ return to_time_string(uptime());
+}
+
+std::string OS::uptime_process()
+{
+ std::string filepath{"/proc/self/stat"};
+ std::ifstream f(filepath, std::ios::in);
+ if (f.is_open()) {
+ std::string line;
+ std::getline(f, line);
+ std::vector<std::string> elements;
+ boost::algorithm::split(elements, line, [](char c){ return c == ' '; });
+ if (elements.size() < 22)
+ throw std::runtime_error("Bad contents of /proc/self/stat");
+
+ long jiffies_per_second {sysconf(_SC_CLK_TCK)};
+ if (jiffies_per_second == 0)
+ throw std::runtime_error("Jiffies per second is 0");
+
+ try {
+ unsigned long starttime { std::stoul(elements[21])};
+
+ unsigned long runtime = uptime() - starttime / jiffies_per_second;
+
+ return to_time_string(runtime);
+ } catch (const std::exception& ex) {
+ throw std::runtime_error("Bad value in /proc/self/stat: "s + ex.what());
+ }
+
+ } else
+ throw std::runtime_error("Reading /proc/self/stat");
+}
+