#include "os.h" #include #include #include #include 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(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 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"); }