From 4a60ddb9a78a86705067ea2cccaea177a047b34b Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Wed, 4 Nov 2015 21:15:27 +0100 Subject: [PATCH] * Implemented cpu_info(), system_product_name() and os_description() for Linux. --- common/os/linux/system_info.cpp | 173 ++++++++++++++++++++++++++++++-- 1 file changed, 166 insertions(+), 7 deletions(-) diff --git a/common/os/linux/system_info.cpp b/common/os/linux/system_info.cpp index f1da76a70..4b05d86e9 100644 --- a/common/os/linux/system_info.cpp +++ b/common/os/linux/system_info.cpp @@ -21,24 +21,183 @@ #include "../system_info.h" +#include "../../memory.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + namespace caspar { - + +namespace detail { + + class functor_line_filter : public boost::iostreams::wline_filter + { + std::function func_; + public: + template + functor_line_filter(const Func& func) + : func_(func) + { + } + + std::wstring do_filter(const std::wstring& in) override + { + return func_(in); + } + }; + + class truncate_duplicates : public boost::iostreams::wline_filter + { + std::set seen_; + public: + std::wstring do_filter(const std::wstring& in) override + { + auto previously_not_seen = seen_.insert(in).second; + + if (previously_not_seen) + return in; + else + return L""; + } + }; + +} // namespace detail + +std::wstring consume(std::shared_ptr&& in) +{ + return std::wstring(std::istreambuf_iterator(*in), std::istreambuf_iterator()); +} + +template +std::shared_ptr operator|(std::shared_ptr in, const Filter& filter) +{ + spl::shared_ptr filtered; + filtered->push(filter); + filtered->push(*in); + + return std::shared_ptr( + filtered.get(), + [in, filtered](boost::iostreams::filtering_wistream* p) {}); +} + +// Commands + +std::shared_ptr cat(const std::string& file) +{ + return std::make_shared(file); +} + +boost::iostreams::wgrep_filter grep(const std::wstring& pattern) +{ + return boost::iostreams::wgrep_filter(boost::wregex(pattern)); +} + +detail::functor_line_filter cut(const std::wstring& delimiter, int column) +{ + return detail::functor_line_filter([=](const std::wstring& line) + { + std::vector result; + boost::algorithm::split(result, line, boost::is_any_of(delimiter), boost::algorithm::token_compress_on); + return result.at(column); + }); +} + +detail::functor_line_filter trim() +{ + return detail::functor_line_filter([](const std::wstring& line) { return boost::trim_copy(line); }); +} + +struct wc : boost::iostreams::aggregate_filter +{ + void do_filter(const std::vector& src, std::vector& dest) override + { + auto line_count = boost::range::count(src, L'\n') + 4; + auto out = boost::lexical_cast(line_count); + dest.insert(dest.begin(), out.begin(), out.end()); + dest.push_back('\n'); + } +}; + +struct remove_empty_lines : boost::iostreams::aggregate_filter +{ + void do_filter(const std::vector& src, std::vector& dest) override + { + bool last_was_newline = false; + + for (auto iter = src.begin(), end = src.end(); iter != end; ++iter) + { + auto current = *iter; + auto is_newline = current == '\n'; + + if (is_newline && (last_was_newline || iter == src.begin())) + continue; + + dest.push_back(current); + last_was_newline = is_newline; + } + + if (!dest.empty() && dest.back() == '\n') + dest.pop_back(); + } +}; + +boost::iostreams::composite uniq() +{ + return boost::iostreams::compose(remove_empty_lines(), detail::truncate_duplicates()); +} + std::wstring cpu_info() { - // TODO: implement - return L"Unknown CPU"; + try + { + auto num_physical_threads = consume(cat("/proc/cpuinfo") | grep(L"model name") | wc() | remove_empty_lines()); + auto processor_names = consume(cat("/proc/cpuinfo") | grep(L"model name") | cut(L":", 1) | trim() | uniq()); + + return processor_names + L" Physical threads: " + num_physical_threads; + } + catch (...) + { + return L"Unknown CPU"; + } } std::wstring system_product_name() { - // TODO: implement - return L"Unknown System"; + try + { + return consume(cat("/sys/devices/virtual/dmi/id/product_name") | remove_empty_lines()); + } + catch (...) + { + return L"Unknown System"; + } } std::wstring os_description() { - // TODO: implement - return L"Unknown OS"; + try + { + return consume(cat("/etc/issue.net") | remove_empty_lines()); + } + catch (...) + { + return L"Unknown OS"; + } } } + -- 2.39.2