From c397f9cedfb04c5e75a684f3f3e618a720d82790 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Mon, 3 Mar 2014 16:36:36 +0100 Subject: [PATCH] Add support for dynamic values in sysfs --- kernel/include/fs/sysfs.hpp | 6 ++++- kernel/src/fs/sysfs.cpp | 51 ++++++++++++++++++++++++++++++++----- kernel/src/kernel.cpp | 4 +-- kernel/src/timer.cpp | 8 +++--- kernel/src/vesa.cpp | 6 ++--- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/kernel/include/fs/sysfs.hpp b/kernel/include/fs/sysfs.hpp index 1e6dc631..c9224338 100644 --- a/kernel/include/fs/sysfs.hpp +++ b/kernel/include/fs/sysfs.hpp @@ -33,7 +33,11 @@ public: size_t rm(const std::vector& file_path); }; -void set_value(const std::string& mount_point, const std::string& path, const std::string& value); +typedef std::string (*dynamic_fun_t)(); + +void set_constant_value(const std::string& mount_point, const std::string& path, const std::string& value); +void set_dynamic_value(const std::string& mount_point, const std::string& path, dynamic_fun_t fun); + void delete_value(const std::string& mount_point, const std::string& path); void delete_folder(const std::string& mount_point, const std::string& path); diff --git a/kernel/src/fs/sysfs.cpp b/kernel/src/fs/sysfs.cpp index 88e1720b..1c56398c 100644 --- a/kernel/src/fs/sysfs.cpp +++ b/kernel/src/fs/sysfs.cpp @@ -19,12 +19,25 @@ namespace { struct sys_value { std::string name; - std::string value; + std::string _value; + sysfs::dynamic_fun_t fun = nullptr; sys_value(){} - sys_value(std::string name, std::string value) : name(name), value(value){ + sys_value(std::string name, std::string value) : name(name), _value(value){ //Nothing else to init } + + sys_value(std::string name, sysfs::dynamic_fun_t fun) : name(name), fun(fun){ + //Nothing else to init + } + + std::string value() const { + if(fun){ + return fun(); + } else { + return _value; + } + } }; struct sys_folder { @@ -110,7 +123,7 @@ size_t get_file(const sys_folder& folder, const std::vector& file_p f.directory = false; f.hidden = false; f.system = false; - f.size = file.value.size(); + f.size = file.value().size(); return 0; } @@ -136,7 +149,7 @@ size_t ls(const sys_folder& folder, std::vector& contents){ f.directory = false; f.hidden = false; f.system = false; - f.size = file.value.size(); + f.size = file.value().size(); contents.push_back(f); } @@ -146,7 +159,7 @@ size_t ls(const sys_folder& folder, std::vector& contents){ size_t read(const sys_folder& folder, const std::vector& file_path, std::string& content){ for(auto& file : folder.values){ if(file.name == file_path.back()){ - content = file.value; + content = file.value(); return 0; } } @@ -163,7 +176,7 @@ size_t read(const sys_folder& folder, const std::vector& file_path, void set_value(sys_folder& folder, const std::string& name, const std::string& value){ for(auto& v : folder.values){ if(v.name == name){ - v.value = value; + v._value = value; return; } } @@ -171,6 +184,17 @@ void set_value(sys_folder& folder, const std::string& name, const std::string& v folder.values.emplace_back(name, value); } +void set_value(sys_folder& folder, const std::string& name, sysfs::dynamic_fun_t fun){ + for(auto& v : folder.values){ + if(v.name == name){ + v.fun = fun; + return; + } + } + + folder.values.emplace_back(name, fun); +} + void delete_value(sys_folder& folder, const std::string& name){ for(size_t i = 0; i < folder.values.size(); ++i){ auto& v = folder.values[i]; @@ -280,7 +304,7 @@ size_t sysfs::sysfs_file_system::statfs(statfs_info& file){ return 0; } -void sysfs::set_value(const std::string& mount_point, const std::string& path, const std::string& value){ +void sysfs::set_constant_value(const std::string& mount_point, const std::string& path, const std::string& value){ auto& root_folder = find_root_folder(mount_point); auto file_path = std::split(path, '/'); @@ -293,6 +317,19 @@ void sysfs::set_value(const std::string& mount_point, const std::string& path, c } } +void sysfs::set_dynamic_value(const std::string& mount_point, const std::string& path, dynamic_fun_t fun){ + auto& root_folder = find_root_folder(mount_point); + + auto file_path = std::split(path, '/'); + + if(file_path.size() == 1){ + ::set_value(root_folder, file_path.back(), fun); + } else { + auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + ::set_value(folder, file_path.back(), fun); + } +} + void sysfs::delete_value(const std::string& mount_point, const std::string& path){ auto& root_folder = find_root_folder(mount_point); diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index d596fd50..34a0ae08 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -84,8 +84,8 @@ void kernel_main(){ init_console(); - sysfs::set_value("/sys/", "version", "0.1"); - sysfs::set_value("/sys/", "author", "Baptiste Wicht"); + sysfs::set_constant_value("/sys/", "version", "0.1"); + sysfs::set_constant_value("/sys/", "author", "Baptiste Wicht"); scheduler::init(); diff --git a/kernel/src/timer.cpp b/kernel/src/timer.cpp index 4a777a15..3ac69df7 100644 --- a/kernel/src/timer.cpp +++ b/kernel/src/timer.cpp @@ -19,12 +19,16 @@ uint64_t _timer_seconds = 0; volatile uint64_t _timer_countdown = 0; +std::string sysfs_uptime(){ + return std::to_string(timer::seconds()); +} + } //End of anonymous namespace void timer::install(){ pit::install(); - sysfs::set_value("/sys/", "uptime", "0"); + sysfs::set_dynamic_value("/sys/", "uptime", &sysfs_uptime); } void timer::tick(){ @@ -38,8 +42,6 @@ void timer::tick(){ if(_timer_ticks % 1000 == 0){ ++_timer_seconds; - - sysfs::set_value("/sys/", "uptime", std::to_string(_timer_seconds)); } } diff --git a/kernel/src/vesa.cpp b/kernel/src/vesa.cpp index 89c0bbe4..e56998c0 100644 --- a/kernel/src/vesa.cpp +++ b/kernel/src/vesa.cpp @@ -77,9 +77,9 @@ bool vesa::init(){ screen = reinterpret_cast(virt); - sysfs::set_value("/sys/", "/vesa/enabled", "true"); - sysfs::set_value("/sys/", "/vesa/resolution/width", std::to_string(block.width)); - sysfs::set_value("/sys/", "/vesa/resolution/height", std::to_string(block.height)); + sysfs::set_constant_value("/sys/", "/vesa/enabled", "true"); + sysfs::set_constant_value("/sys/", "/vesa/resolution/width", std::to_string(block.width)); + sysfs::set_constant_value("/sys/", "/vesa/resolution/height", std::to_string(block.height)); return true; }