diff --git a/kernel/include/fs/devfs.hpp b/kernel/include/fs/devfs.hpp index 7a8c466c..1e524bfa 100644 --- a/kernel/include/fs/devfs.hpp +++ b/kernel/include/fs/devfs.hpp @@ -29,10 +29,10 @@ struct dev_driver { struct devfs_file_system : vfs::file_system { private: - std::string mount_point; + path mount_point; public: - devfs_file_system(std::string mount_point); + devfs_file_system(path mount_point); ~devfs_file_system(); size_t statfs(statfs_info& file); diff --git a/kernel/include/fs/fat32.hpp b/kernel/include/fs/fat32.hpp index e3a0cb5c..a0ce2b81 100644 --- a/kernel/include/fs/fat32.hpp +++ b/kernel/include/fs/fat32.hpp @@ -23,14 +23,14 @@ typedef const disks::disk_descriptor& dd; struct fat32_file_system : vfs::file_system { private: - std::string mount_point; + path mount_point; std::string device; fat_bs_t* fat_bs = nullptr; fat_is_t* fat_is = nullptr; public: - fat32_file_system(std::string mount_point, std::string device); + fat32_file_system(path mount_point, std::string device); ~fat32_file_system(); void init(); diff --git a/kernel/include/fs/procfs.hpp b/kernel/include/fs/procfs.hpp index 247618c2..10c88ac5 100644 --- a/kernel/include/fs/procfs.hpp +++ b/kernel/include/fs/procfs.hpp @@ -20,10 +20,10 @@ namespace procfs { struct procfs_file_system : vfs::file_system { private: - std::string mount_point; + path mount_point; public: - procfs_file_system(std::string mount_point); + procfs_file_system(path mount_point); ~procfs_file_system(); size_t statfs(statfs_info& file); diff --git a/kernel/include/fs/sysfs.hpp b/kernel/include/fs/sysfs.hpp index af74fd62..21d62045 100644 --- a/kernel/include/fs/sysfs.hpp +++ b/kernel/include/fs/sysfs.hpp @@ -18,10 +18,10 @@ namespace sysfs { struct sysfs_file_system : vfs::file_system { private: - std::string mount_point; + path mount_point; public: - sysfs_file_system(std::string mount_point); + sysfs_file_system(path mount_point); ~sysfs_file_system(); size_t statfs(statfs_info& file); @@ -38,12 +38,12 @@ public: 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 set_constant_value(const path& mount_point, const path& file_path, const std::string& value); +void set_dynamic_value(const path& mount_point, const path& file_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); +void delete_value(const path& mount_point, const path& file_path); +void delete_folder(const path& mount_point, const path& file_path); -} +} //end of namespace sysfs #endif diff --git a/kernel/include/vfs/path.hpp b/kernel/include/vfs/path.hpp index 47ad1f77..0ed4a7e1 100644 --- a/kernel/include/vfs/path.hpp +++ b/kernel/include/vfs/path.hpp @@ -20,6 +20,7 @@ struct path { path(); path(const std::string& path); path(const path& base_path, const std::string& path); + path(const path& base_path, const path& p); path(const path&) = default; path(path&&) = default; @@ -38,8 +39,13 @@ struct path { bool empty() const; bool is_root() const; bool is_valid() const; + bool is_sub_root() const; size_t size() const; std::string base_name() const; + std::string root_name() const; + std::string sub_root_name() const; + bool is_absolute() const; + bool is_relative() const; // Accessors to sub parts const std::string& name(size_t i) const; @@ -47,13 +53,22 @@ struct path { // Decomposition functions path sub_path(size_t i) const; + path branch_path() const; // Iterators iterator begin() const ; iterator end() const ; + // relational operators + bool operator==(const path& p) const; + bool operator!=(const path& p) const; + private: std::vector names; }; +path operator/(const path& lhs, const path& rhs); +path operator/(const path& lhs, const std::string& rhs); +path operator/(const std::string& lhs, const path& rhs); + #endif diff --git a/kernel/src/disks.cpp b/kernel/src/disks.cpp index 0315b3cb..d062fa74 100644 --- a/kernel/src/disks.cpp +++ b/kernel/src/disks.cpp @@ -108,11 +108,9 @@ void disks::detect_disks(){ } } - std::string path = "/ata/" + name; - - sysfs::set_constant_value("/sys/", path + "/model", descriptor.model); - sysfs::set_constant_value("/sys/", path + "/serial", descriptor.serial); - sysfs::set_constant_value("/sys/", path + "/firmware", descriptor.firmware); + sysfs::set_constant_value(path("/sys"), path("/ata") / name / "model", descriptor.model); + sysfs::set_constant_value(path("/sys"), path("/ata") / name / "serial", descriptor.serial); + sysfs::set_constant_value(path("/sys"), path("/ata") / name / "firmware", descriptor.firmware); ++number_of_disks; } diff --git a/kernel/src/fs/devfs.cpp b/kernel/src/fs/devfs.cpp index 8e3e9c83..f7c13d10 100644 --- a/kernel/src/fs/devfs.cpp +++ b/kernel/src/fs/devfs.cpp @@ -29,18 +29,18 @@ struct device { }; struct device_list { - std::string name; + path mount_point; std::vector devices; device_list(){}; - device_list(std::string name) : name(name){} + device_list(path mp) : mount_point(mp){} }; std::vector devices; } //end of anonymous namespace -devfs::devfs_file_system::devfs_file_system(std::string mp) : mount_point(mp) { +devfs::devfs_file_system::devfs_file_system(path mp) : mount_point(mp) { //Nothing to init } @@ -49,7 +49,7 @@ devfs::devfs_file_system::~devfs_file_system(){ } size_t devfs::devfs_file_system::get_file(const path& file_path, vfs::file& f){ - if(file_path.empty()){ + if(file_path.is_root()){ f.file_name = "/"; f.directory = true; f.hidden = false; @@ -60,12 +60,12 @@ size_t devfs::devfs_file_system::get_file(const path& file_path, vfs::file& f){ } //No subfolder support - if(file_path.size() > 1){ + if(file_path.size() > 2){ return std::ERROR_NOT_EXISTS; } for(auto& device_list : devices){ - if(device_list.name == mount_point){ + if(device_list.mount_point == mount_point){ for(auto& device : device_list.devices){ if(device.name == file_path.base_name()){ f.file_name = device.name; @@ -85,12 +85,12 @@ size_t devfs::devfs_file_system::get_file(const path& file_path, vfs::file& f){ size_t devfs::devfs_file_system::read(const path& file_path, char* buffer, size_t count, size_t offset, size_t& read){ //Cannot access the root for reading - if(file_path.empty()){ + if(file_path.is_root()){ return std::ERROR_PERMISSION_DENIED; } for(auto& device_list : devices){ - if(device_list.name == mount_point){ + if(device_list.mount_point == mount_point){ for(auto& device : device_list.devices){ if(device.name == file_path.base_name()){ if(!device.driver){ @@ -108,12 +108,12 @@ size_t devfs::devfs_file_system::read(const path& file_path, char* buffer, size_ size_t devfs::devfs_file_system::write(const path& file_path, const char* buffer, size_t count, size_t offset, size_t& written){ //Cannot access the root for writing - if(file_path.empty()){ + if(file_path.is_root()){ return std::ERROR_PERMISSION_DENIED; } for(auto& device_list : devices){ - if(device_list.name == mount_point){ + if(device_list.mount_point == mount_point){ for(auto& device : device_list.devices){ if(device.name == file_path.base_name()){ if(!device.driver){ @@ -131,12 +131,12 @@ size_t devfs::devfs_file_system::write(const path& file_path, const char* buffer size_t devfs::devfs_file_system::clear(const path& file_path, size_t count, size_t offset, size_t& written){ //Cannot access the root for writing - if(file_path.empty()){ + if(file_path.is_root()){ return std::ERROR_PERMISSION_DENIED; } for(auto& device_list : devices){ - if(device_list.name == mount_point){ + if(device_list.mount_point == mount_point){ for(auto& device : device_list.devices){ if(device.name == file_path.base_name()){ if(!device.driver){ @@ -158,12 +158,12 @@ size_t devfs::devfs_file_system::truncate(const path&, size_t){ size_t devfs::devfs_file_system::ls(const path& file_path, std::vector& contents){ //No subfolder support - if(file_path.size() > 0){ + if(file_path.size() > 1){ return std::ERROR_NOT_EXISTS; } for(auto& device_list : devices){ - if(device_list.name == mount_point){ + if(device_list.mount_point == mount_point){ for(auto& device : device_list.devices){ vfs::file f; f.file_name = device.name; @@ -202,7 +202,7 @@ size_t devfs::devfs_file_system::statfs(statfs_info& file){ void devfs::register_device(const std::string& mp, const std::string& name, device_type type, dev_driver* driver, void* data){ for(auto& device_list : devices){ - if(device_list.name == mp){ + if(device_list.mount_point == mp){ device_list.devices.emplace_back(name, type, driver, data); return; } @@ -214,7 +214,7 @@ void devfs::register_device(const std::string& mp, const std::string& name, devi void devfs::deregister_device(const std::string& mp, const std::string& name){ for(auto& device_list : devices){ - if(device_list.name == mp){ + if(device_list.mount_point == mp){ for(size_t i = 0; i < device_list.devices.size(); ++i){ if(device_list.devices[i].name == name){ device_list.devices.erase(i); @@ -228,17 +228,14 @@ void devfs::deregister_device(const std::string& mp, const std::string& name){ } uint64_t devfs::get_device_size(const path& device_name, size_t& size){ - if(device_name.size() != 2){ + if(device_name.size() != 3){ return std::ERROR_INVALID_DEVICE; } - // TODO store the mount point with the slash - std::string mp("/" + device_name[0] + "/"); - for(auto& device_list : devices){ - if(device_list.name == mp){ + if(device_list.mount_point == device_name.branch_path()){ for(auto& device : device_list.devices){ - if(device.name == device_name[1]){ + if(device.name == device_name.base_name()){ if(device.type == device_type::BLOCK_DEVICE){ size = device.driver->size(device.data); diff --git a/kernel/src/fs/fat32.cpp b/kernel/src/fs/fat32.cpp index 64755b96..0ef4247c 100644 --- a/kernel/src/fs/fat32.cpp +++ b/kernel/src/fs/fat32.cpp @@ -171,7 +171,7 @@ void init_file_entry(fat32::cluster_entry* entry_ptr, const char* name, uint32_t } //end of anonymous namespace -fat32::fat32_file_system::fat32_file_system(std::string mount_point, std::string device) : mount_point(mount_point), device(device) { +fat32::fat32_file_system::fat32_file_system(path mount_point, std::string device) : mount_point(mount_point), device(device) { //Nothing else to init } @@ -1204,11 +1204,11 @@ std::vector fat32::fat32_file_system::files(uint32_t cluster_number){ std::pair fat32::fat32_file_system::find_cluster_number(const path& file_path, size_t last){ auto cluster_number = fat_bs->root_directory_cluster_start; - if(file_path.size() - last == 0){ + if(file_path.size() - last == 1){ return std::make_pair(true, cluster_number); } - for(size_t i = 0; i < file_path.size() - last; ++i){ + for(size_t i = 1; i < file_path.size() - last; ++i){ auto& p = file_path[i]; bool found = false; diff --git a/kernel/src/fs/procfs.cpp b/kernel/src/fs/procfs.cpp index bfff45bb..56c4b6a0 100644 --- a/kernel/src/fs/procfs.cpp +++ b/kernel/src/fs/procfs.cpp @@ -61,7 +61,7 @@ void procfs::set_pcb(const scheduler::process_control_t* pcb_ptr){ pcb = pcb_ptr; } -procfs::procfs_file_system::procfs_file_system(std::string mp) : mount_point(mp) { +procfs::procfs_file_system::procfs_file_system(path mp) : mount_point(mp) { standard_contents.reserve(7); standard_contents.emplace_back("pid", false, false, false, 0); standard_contents.emplace_back("ppid", false, false, false, 0); @@ -78,7 +78,7 @@ procfs::procfs_file_system::~procfs_file_system(){ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f){ // Access the root folder - if(file_path.empty()){ + if(file_path.is_root()){ f.file_name = "/"; f.directory = true; f.hidden = false; @@ -88,7 +88,7 @@ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f) return 0; } - auto i = atoui(file_path[0]); + auto i = atoui(file_path[1]); // Check the pid folder if(i >= scheduler::MAX_PROCESS){ @@ -102,8 +102,8 @@ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f) } // Access a pid folder - if(file_path.size() == 1){ - f.file_name = file_path[0]; + if(file_path.size() == 2){ + f.file_name = file_path[1]; f.directory = true; f.hidden = false; f.system = false; @@ -113,11 +113,11 @@ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f) } // Access a file directly - if(file_path.size() == 2){ - auto value = get_value(i, file_path[1]); + if(file_path.size() == 3){ + auto value = get_value(i, file_path[2]); if(value.size()){ - f.file_name = file_path[1]; + f.file_name = file_path[2]; f.directory = false; f.hidden = false; f.system = false; @@ -135,12 +135,12 @@ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f) size_t procfs::procfs_file_system::read(const path& file_path, char* buffer, size_t count, size_t offset, size_t& read){ //Cannot access the root nor the pid directores for reading - if(file_path.size() < 2){ + if(file_path.size() < 3){ return std::ERROR_PERMISSION_DENIED; } - if(file_path.size() == 2){ - auto i = atoui(file_path[0]); + if(file_path.size() == 3){ + auto i = atoui(file_path[1]); if(i >= scheduler::MAX_PROCESS){ return std::ERROR_NOT_EXISTS; @@ -152,7 +152,7 @@ size_t procfs::procfs_file_system::read(const path& file_path, char* buffer, siz return std::ERROR_NOT_EXISTS; } - auto value = get_value(i, file_path[1]); + auto value = get_value(i, file_path[2]); if(value.size()){ return ::read(value, buffer, count, offset, read); @@ -165,9 +165,7 @@ size_t procfs::procfs_file_system::read(const path& file_path, char* buffer, siz } size_t procfs::procfs_file_system::ls(const path& file_path, std::vector& contents){ - logging::logf(logging::log_level::DEBUG, "procfs ls %u\n", file_path.size()); - - if(file_path.size() == 0){ + if(file_path.is_root()){ for(size_t i = 0; i < scheduler::MAX_PROCESS; ++i){ auto& process = pcb[i]; @@ -185,7 +183,7 @@ size_t procfs::procfs_file_system::ls(const path& file_path, std::vector root_folders; -sys_folder& find_root_folder(const std::string& mount_point){ +sys_folder& find_root_folder(const path& mount_point){ + thor_assert(mount_point.is_sub_root(), "Unsupported mount point"); + for(auto& sys_folder : root_folders){ - if(sys_folder.name == mount_point){ + if(sys_folder.name == mount_point.sub_root_name()){ return sys_folder; } } - root_folders.emplace_back(mount_point); + root_folders.emplace_back(mount_point.sub_root_name()); return root_folders.back(); } @@ -227,7 +230,7 @@ void delete_folder(sys_folder& folder, const std::string& name){ } //end of anonymous namespace -sysfs::sysfs_file_system::sysfs_file_system(std::string mp) : mount_point(mp) { +sysfs::sysfs_file_system::sysfs_file_system(path mp) : mount_point(mp) { //Nothing to init } @@ -238,7 +241,7 @@ sysfs::sysfs_file_system::~sysfs_file_system(){ size_t sysfs::sysfs_file_system::get_file(const path& file_path, vfs::file& f){ auto& root_folder = find_root_folder(mount_point); - if(file_path.empty()){ + if(file_path.is_root()){ f.file_name = "/"; f.directory = true; f.hidden = false; @@ -246,11 +249,11 @@ size_t sysfs::sysfs_file_system::get_file(const path& file_path, vfs::file& f){ f.size = 0; return 0; - } else if(file_path.size() == 1){ + } else if(file_path.size() == 2){ return ::get_file(root_folder, file_path, f); } else { - if(exists_folder(root_folder, file_path, 0, file_path.size() - 1)){ - auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + if(exists_folder(root_folder, file_path, 1, file_path.size() - 1)){ + auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1); return ::get_file(folder, file_path, f); } @@ -262,13 +265,13 @@ size_t sysfs::sysfs_file_system::get_file(const path& file_path, vfs::file& f){ size_t sysfs::sysfs_file_system::read(const path& file_path, char* buffer, size_t count, size_t offset, size_t& read){ auto& root_folder = find_root_folder(mount_point); - if(file_path.empty()){ + if(file_path.is_root()){ return std::ERROR_DIRECTORY; - } else if(file_path.size() == 1){ + } else if(file_path.size() == 2){ return ::read(root_folder, file_path, buffer, count, offset, read); } else { - if(exists_folder(root_folder, file_path, 0, file_path.size() - 1)){ - auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + if(exists_folder(root_folder, file_path, 1, file_path.size() - 1)){ + auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1); return ::read(folder, file_path, buffer, count, offset, read); } @@ -292,11 +295,11 @@ size_t sysfs::sysfs_file_system::truncate(const path&, size_t){ size_t sysfs::sysfs_file_system::ls(const path& file_path, std::vector& contents){ auto& root_folder = find_root_folder(mount_point); - if(file_path.empty()){ + if(file_path.is_root()){ return ::ls(root_folder, contents); } else { - if(exists_folder(root_folder, file_path, 0, file_path.size())){ - auto& folder = find_folder(root_folder, file_path, 0, file_path.size()); + if(exists_folder(root_folder, file_path, 1, file_path.size())){ + auto& folder = find_folder(root_folder, file_path, 1, file_path.size()); return ::ls(folder, contents); } @@ -324,55 +327,47 @@ size_t sysfs::sysfs_file_system::statfs(statfs_info& file){ return 0; } -void sysfs::set_constant_value(const std::string& mount_point, const std::string& p, const std::string& value){ +void sysfs::set_constant_value(const path& mount_point, const path& file_path, const std::string& value){ auto& root_folder = find_root_folder(mount_point); - path file_path(p); - - if(file_path.size() == 1){ + if(file_path.size() == 2){ ::set_value(root_folder, file_path.base_name(), value); } else { - auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1); ::set_value(folder, file_path.base_name(), value); } } -void sysfs::set_dynamic_value(const std::string& mount_point, const std::string& p, dynamic_fun_t fun){ +void sysfs::set_dynamic_value(const path& mount_point, const path& file_path, dynamic_fun_t fun){ auto& root_folder = find_root_folder(mount_point); - path file_path(p); - - if(file_path.size() == 1){ + if(file_path.size() == 2){ ::set_value(root_folder, file_path.base_name(), fun); } else { - auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1); ::set_value(folder, file_path.base_name(), fun); } } -void sysfs::delete_value(const std::string& mount_point, const std::string& p){ +void sysfs::delete_value(const path& mount_point, const path& file_path){ auto& root_folder = find_root_folder(mount_point); - path file_path(p); - - if(file_path.size() == 1){ + if(file_path.size() == 2){ ::delete_value(root_folder, file_path.base_name()); } else { - auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1); ::delete_value(folder, file_path.base_name()); } } -void sysfs::delete_folder(const std::string& mount_point, const std::string& p){ +void sysfs::delete_folder(const path& mount_point, const path& file_path){ auto& root_folder = find_root_folder(mount_point); - path file_path(p); - - if(file_path.size() == 1){ + if(file_path.size() == 2){ ::delete_folder(root_folder, file_path.base_name()); } else { - auto& folder = find_folder(root_folder, file_path, 0, file_path.size() - 1); + auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1); ::delete_folder(folder, file_path.base_name()); } diff --git a/kernel/src/kalloc.cpp b/kernel/src/kalloc.cpp index 5feb8492..b2359693 100644 --- a/kernel/src/kalloc.cpp +++ b/kernel/src/kalloc.cpp @@ -332,9 +332,9 @@ void kalloc::init(){ } void kalloc::finalize(){ - sysfs::set_dynamic_value("/sys/", "/memory/dynamic/free", &sysfs_free); - sysfs::set_dynamic_value("/sys/", "/memory/dynamic/used", &sysfs_used); - sysfs::set_dynamic_value("/sys/", "/memory/dynamic/allocated", &sysfs_allocated); + sysfs::set_dynamic_value(path("/sys"), path("/memory/dynamic/free"), &sysfs_free); + sysfs::set_dynamic_value(path("/sys"), path("/memory/dynamic/used"), &sysfs_used); + sysfs::set_dynamic_value(path("/sys"), path("/memory/dynamic/allocated"), &sysfs_allocated); } void* kalloc::k_malloc(uint64_t bytes){ diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 0a5975da..08837fb8 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -121,8 +121,8 @@ void kernel_main(){ //Only install system calls when everything else is ready install_system_calls(); - sysfs::set_constant_value("/sys/", "version", "0.1"); - sysfs::set_constant_value("/sys/", "author", "Baptiste Wicht"); + sysfs::set_constant_value(path("/sys"), path("/version"), "0.1"); + sysfs::set_constant_value(path("/sys"), path("/author"), "Baptiste Wicht"); // Initialize the scheduler scheduler::init(); diff --git a/kernel/src/network.cpp b/kernel/src/network.cpp index 124e8c8c..b2c8e7fe 100644 --- a/kernel/src/network.cpp +++ b/kernel/src/network.cpp @@ -84,13 +84,13 @@ void network::init(){ rtl8139::init_driver(interface, pci_device); } - std::string path = "/net/" + interface.name; + auto p = path("/net") / interface.name; - sysfs::set_constant_value("/sys/", path + "/name", interface.name); - sysfs::set_constant_value("/sys/", path + "/driver", interface.driver); - sysfs::set_constant_value("/sys/", path + "/enabled", interface.enabled ? "true" : "false"); - sysfs::set_constant_value("/sys/", path + "/pci_device", std::to_string(i)); - sysfs::set_constant_value("/sys/", path + "/mac", std::to_string(interface.mac_address)); + sysfs::set_constant_value(path("/sys"), p / "name", interface.name); + sysfs::set_constant_value(path("/sys"), p / "driver", interface.driver); + sysfs::set_constant_value(path("/sys"), p / "enabled", interface.enabled ? "true" : "false"); + sysfs::set_constant_value(path("/sys"), p / "pci_device", std::to_string(i)); + sysfs::set_constant_value(path("/sys"), p / "mac", std::to_string(interface.mac_address)); ++index; } diff --git a/kernel/src/paging.cpp b/kernel/src/paging.cpp index 274d947b..f21515ca 100644 --- a/kernel/src/paging.cpp +++ b/kernel/src/paging.cpp @@ -266,11 +266,11 @@ void paging::init(){ } void paging::finalize(){ - sysfs::set_constant_value("/sys/", "/paging/page_size", std::to_string(paging::PAGE_SIZE)); - sysfs::set_constant_value("/sys/", "/paging/pdpt", std::to_string(paging::pml4_entries)); - sysfs::set_constant_value("/sys/", "/paging/pd", std::to_string(paging::pdpt_entries)); - sysfs::set_constant_value("/sys/", "/paging/pt", std::to_string(paging::pd_entries)); - sysfs::set_constant_value("/sys/", "/paging/physical_size", std::to_string(paging::physical_memory_pages * paging::PAGE_SIZE)); + sysfs::set_constant_value(path("/sys"), path("/paging/page_size"), std::to_string(paging::PAGE_SIZE)); + sysfs::set_constant_value(path("/sys"), path("/paging/pdpt"), std::to_string(paging::pml4_entries)); + sysfs::set_constant_value(path("/sys"), path("/paging/pd"), std::to_string(paging::pdpt_entries)); + sysfs::set_constant_value(path("/sys"), path("/paging/pt"), std::to_string(paging::pd_entries)); + sysfs::set_constant_value(path("/sys"), path("/paging/physical_size"), std::to_string(paging::physical_memory_pages * paging::PAGE_SIZE)); } size_t paging::pages(size_t size){ diff --git a/kernel/src/path.cpp b/kernel/src/path.cpp index dc042a57..f0021946 100644 --- a/kernel/src/path.cpp +++ b/kernel/src/path.cpp @@ -7,21 +7,30 @@ #include "vfs/path.hpp" +#include "assert.hpp" + path::path(){ //Nothing to init } path::path(const std::string& path){ + if(path[0] == '/'){ + names.push_back("/"); + } + auto parts = std::split(path, '/'); - names.reserve(parts.size()); + names.reserve(names.size() + parts.size()); + for(auto& part : parts){ names.push_back(part); } } -path::path(const path& base_path, const std::string& path){ - auto parts = std::split(path, '/'); - names.reserve(base_path.size() + parts.size()); +path::path(const path& base_path, const std::string& p){ + thor_assert(p.empty() || p[0] != '/', "Impossible to add absolute path to another path"); + + auto parts = std::split(p, '/'); + names.reserve(names.size() + base_path.size() + parts.size()); for(auto& part : base_path){ names.push_back(part); @@ -32,16 +41,40 @@ path::path(const path& base_path, const std::string& path){ } } -// TODO Ideally, the last / should not be used -std::string path::string() const { - std::string path("/"); +path::path(const path& base_path, const path& p){ + thor_assert(p.is_relative(), "Impossible to add absolute path to another path"); - for(auto& part : names){ - path += part; - path += '/'; + names.reserve(names.size() + base_path.size() + p.size()); + + for(auto& part : base_path){ + names.push_back(part); } - return path; + for(auto& part : p){ + names.push_back(part); + } +} + +// TODO Ideally, the last / should not be used +std::string path::string() const { + std::string str_path; + + size_t i = 0; + + if(is_absolute()){ + str_path = "/"; + i = 1; + } + + std::string comma; + for(; i < names.size(); ++i){ + str_path += comma; + str_path += names[i]; + + comma = "/"; + } + + return str_path; } const std::vector& path::vec() const { @@ -58,11 +91,15 @@ bool path::empty() const { } bool path::is_root() const { - return names.empty(); + return names.size() == 1 && names[0] == "/"; } bool path::is_valid() const { - return !(names.size() == 1 && names[0] == "//"); + return !names.empty() && !(names.size() == 1 && names[0] == "//"); +} + +bool path::is_sub_root() const { + return is_absolute() && names.size() == 2; } size_t path::size() const { @@ -77,6 +114,30 @@ std::string path::base_name() const { } } +std::string path::root_name() const { + if(empty()){ + return ""; + } else { + return names.front(); + } +} + +std::string path::sub_root_name() const { + if(size() < 2){ + return ""; + } else { + return names[1]; + } +} + +bool path::is_absolute() const { + return names.size() && names[0] == "/"; +} + +bool path::is_relative() const { + return names.size() && names[0] != "/"; +} + const std::string& path::name(size_t i) const { return names[i]; } @@ -92,6 +153,25 @@ path path::sub_path(size_t i) const { return p; } +path path::branch_path() const { + if(empty()){ + return *this; + } + + if(is_root()){ + return *this; + } + + if(is_relative() && size() == 1){ + return *this; + } + + path p; + p.names.resize(size() - 1); + std::copy(p.names.begin(), names.begin(), names.end() - 1); + return p; +} + path::iterator path::begin() const { return names.begin(); } @@ -99,3 +179,23 @@ path::iterator path::begin() const { path::iterator path::end() const { return names.end(); } + +bool path::operator==(const path& p) const { + return names == p.names; +} + +bool path::operator!=(const path& p) const { + return names != p.names; +} + +path operator/(const path& lhs, const path& rhs){ + return {lhs, rhs}; +} + +path operator/(const path& lhs, const std::string& rhs){ + return {lhs, rhs}; +} + +path operator/(const std::string& lhs, const path& rhs){ + return {path(lhs), rhs}; +} diff --git a/kernel/src/pci.cpp b/kernel/src/pci.cpp index 1299664a..79c880ea 100644 --- a/kernel/src/pci.cpp +++ b/kernel/src/pci.cpp @@ -86,12 +86,14 @@ std::vector devices; device_desc.class_type = pci::device_class_type::UNKNOWN; } - std::string path = "/pci/pci:" + std::to_string(bus) + ':' + std::to_string(device) + ':' + std::to_string(function); + std::string pci_name = "pci:" + std::to_string(bus) + ':' + std::to_string(device) + ':' + std::to_string(function); - sysfs::set_constant_value("/sys/", path + "/vendor", std::to_string(vendor_id)); - sysfs::set_constant_value("/sys/", path + "/device", std::to_string(device_id)); - sysfs::set_constant_value("/sys/", path + "/class", std::to_string(class_code)); - sysfs::set_constant_value("/sys/", path + "/subclass", std::to_string(sub_class)); + auto p = path("/pci") / pci_name; + + sysfs::set_constant_value(path("/sys"), p / "vendor", std::to_string(vendor_id)); + sysfs::set_constant_value(path("/sys"), p / "device", std::to_string(device_id)); + sysfs::set_constant_value(path("/sys"), p / "class", std::to_string(class_code)); + sysfs::set_constant_value(path("/sys"), p / "subclass", std::to_string(sub_class)); } void check_device(uint8_t bus, uint8_t device) { diff --git a/kernel/src/physical_allocator.cpp b/kernel/src/physical_allocator.cpp index 0c40cd02..060b4195 100644 --- a/kernel/src/physical_allocator.cpp +++ b/kernel/src/physical_allocator.cpp @@ -164,22 +164,22 @@ void physical_allocator::init(){ } void physical_allocator::finalize(){ - sysfs::set_dynamic_value("/sys/", "/memory/physical/available", &sysfs_available); - sysfs::set_dynamic_value("/sys/", "/memory/physical/free", &sysfs_free); - sysfs::set_dynamic_value("/sys/", "/memory/physical/allocated", &sysfs_allocated); + sysfs::set_dynamic_value(path("/sys"), path("/memory/physical/available"), &sysfs_available); + sysfs::set_dynamic_value(path("/sys"), path("/memory/physical/free"), &sysfs_free); + sysfs::set_dynamic_value(path("/sys"), path("/memory/physical/allocated"), &sysfs_allocated); // Publish the e820 map auto entries = e820::mmap_entry_count(); - sysfs::set_constant_value("/sys/", "/memory/e820/entries", std::to_string(entries)); + sysfs::set_constant_value(path("/sys/"), path("/memory/e820/entries"), std::to_string(entries)); for(size_t i = 0; i < entries; ++i){ auto& entry = e820::mmap_entry(i); - std::string base_path = "/memory/e820/" + std::to_string(i); + auto base_path = path("/memory/e820") / std::to_string(i); - sysfs::set_constant_value("/sys/", base_path + "/base", std::to_string(entry.base)); - sysfs::set_constant_value("/sys/", base_path + "/size", std::to_string(entry.size)); - sysfs::set_constant_value("/sys/", base_path + "/type", e820::str_e820_type(entry.type)); + sysfs::set_constant_value(path("/sys/"), base_path / "base", std::to_string(entry.base)); + sysfs::set_constant_value(path("/sys/"), base_path / "size", std::to_string(entry.size)); + sysfs::set_constant_value(path("/sys/"), base_path / "type", e820::str_e820_type(entry.type)); } } diff --git a/kernel/src/scheduler.cpp b/kernel/src/scheduler.cpp index 07ddf2fb..88686990 100644 --- a/kernel/src/scheduler.cpp +++ b/kernel/src/scheduler.cpp @@ -223,6 +223,9 @@ scheduler::process_t& new_process(){ process.process.brk_start = 0; process.process.brk_end = 0; + // By default, a process is working in root + process.working_directory = path("/"); + return process.process; } diff --git a/kernel/src/timer.cpp b/kernel/src/timer.cpp index 138dd319..853f5e46 100644 --- a/kernel/src/timer.cpp +++ b/kernel/src/timer.cpp @@ -54,7 +54,7 @@ void timer::install(){ suspend_boot(); } - sysfs::set_dynamic_value("/sys/", "uptime", &sysfs_uptime); + sysfs::set_dynamic_value(path("/sys"), path("/uptime"), &sysfs_uptime); } void timer::tick(){ diff --git a/kernel/src/vesa.cpp b/kernel/src/vesa.cpp index 00593a89..5a2fe21d 100644 --- a/kernel/src/vesa.cpp +++ b/kernel/src/vesa.cpp @@ -80,9 +80,9 @@ bool vesa::init(){ screen = reinterpret_cast(virt); - 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)); + sysfs::set_constant_value(path("/sys"), path("/vesa/enabled"), "true"); + sysfs::set_constant_value(path("/sys"), path("/vesa/resolution/width"), std::to_string(block.width)); + sysfs::set_constant_value(path("/sys"), path("/vesa/resolution/height"), std::to_string(block.height)); return true; } diff --git a/kernel/src/vfs/vfs.cpp b/kernel/src/vfs/vfs.cpp index b1e88572..63ed557b 100644 --- a/kernel/src/vfs/vfs.cpp +++ b/kernel/src/vfs/vfs.cpp @@ -26,23 +26,22 @@ #include "console.hpp" #include "logging.hpp" +#include "assert.hpp" namespace { struct mounted_fs { vfs::partition_type fs_type; std::string device; - std::string mount_point; + path mount_point; vfs::file_system* file_system; - std::vector mp_vec; - mounted_fs() = default; - mounted_fs(vfs::partition_type type, std::string dev, std::string mp, vfs::file_system* fs) : + mounted_fs(vfs::partition_type type, std::string dev, path mp, vfs::file_system* fs) : fs_type(type), device(dev), mount_point(mp), file_system(fs) { - mp_vec = std::split(mount_point, '/'); + // Nothing else to init } }; @@ -83,11 +82,13 @@ void mount_proc(){ } path get_path(const char* file_path){ - if(file_path[0] != '/'){ - return {scheduler::get_working_directory(), file_path}; - } else { - return {file_path}; + path p(file_path); + + if(p.is_relative()){ + return scheduler::get_working_directory() / p; } + + return p; } mounted_fs& get_fs(const path& base_path){ @@ -96,7 +97,7 @@ mounted_fs& get_fs(const path& base_path){ if(base_path.is_root()){ for(auto& mp : mount_point_list){ - if(mp.mp_vec.empty()){ + if(mp.mount_point.is_root()){ return mp; } } @@ -106,15 +107,15 @@ mounted_fs& get_fs(const path& base_path){ auto& mp = mount_point_list[i]; bool match = true; - for(size_t j = 0; j < mp.mp_vec.size() && j < base_path.size() ; ++j){ - if(mp.mp_vec[j] != base_path[j]){ + for(size_t j = 0; j < mp.mount_point.size() && j < base_path.size() ; ++j){ + if(mp.mount_point[j] != base_path[j]){ match = false; break; } } - if(match && mp.mp_vec.size() > best){ - best = mp.mp_vec.size(); + if(match && mp.mount_point.size() > best){ + best = mp.mount_point.size(); best_match = i; } } @@ -123,10 +124,17 @@ mounted_fs& get_fs(const path& base_path){ } path get_fs_path(const path& base_path, const mounted_fs& fs){ - return base_path.sub_path(fs.mp_vec.size()); + thor_assert(base_path.is_absolute(), "Invalid base_path in get_fs_path"); + thor_assert(fs.mount_point.is_absolute(), "Invalid base_path in get_fs_path"); + + if(base_path == fs.mount_point){ + return path("/"); + } + + return path("/") / base_path.sub_path(fs.mount_point.size()); } -vfs::file_system* get_new_fs(vfs::partition_type type, const std::string& mount_point, const std::string& device){ +vfs::file_system* get_new_fs(vfs::partition_type type, const path& mount_point, const std::string& device){ switch(type){ case vfs::partition_type::FAT32: return new fat32::fat32_file_system(mount_point, device); @@ -171,48 +179,36 @@ int64_t vfs::mount(partition_type type, size_t mp_fd, size_t dev_fd){ auto& mp_path = scheduler::get_handle(mp_fd); auto& dev_path = scheduler::get_handle(dev_fd); - std::string mp("/"); - - for(auto& p : mp_path){ - mp += p; - mp += "/"; - } - - std::string device("/"); - - for(auto& p : dev_path){ - device += p; - device += "/"; - } - for(auto& m : mount_point_list){ - if(m.mount_point == mp){ + if(m.mount_point == mp_path){ return -std::ERROR_ALREADY_MOUNTED; } } - auto fs = get_new_fs(type, mp, device); + auto fs = get_new_fs(type, mp_path, dev_path.string()); if(!fs){ return -std::ERROR_INVALID_FILE_SYSTEM; } - mount_point_list.emplace_back(type, device, mp, fs); + mount_point_list.emplace_back(type, dev_path.string(), mp_path, fs); fs->init(); - logging::logf(logging::log_level::TRACE, "vfs: mounted file system %s at %s \n", device.c_str(), mp.c_str()); + logging::logf(logging::log_level::TRACE, "vfs: mounted file system %s at %s \n", dev_path.string().c_str(), mp_path.string().c_str()); return 0; } int64_t vfs::mount(partition_type type, const char* mount_point, const char* device){ - auto fs = get_new_fs(type, mount_point, device); + path mp_path(mount_point); + + auto fs = get_new_fs(type, mp_path, device); if(!fs){ return -std::ERROR_INVALID_FILE_SYSTEM; } - mount_point_list.emplace_back(type, device, mount_point, fs); + mount_point_list.emplace_back(type, device, mp_path, fs); return 0; } @@ -239,6 +235,8 @@ int64_t vfs::open(const char* file_path, size_t flags){ auto& fs = get_fs(base_path); auto fs_path = get_fs_path(base_path, fs); + logging::logf(logging::log_level::TRACE, "vfs: open %s:%s \n", base_path.string().c_str(), fs_path.string().c_str()); + //Special handling for opening the root if(fs_path.is_root()){ return scheduler::register_new_handle(base_path); @@ -320,7 +318,7 @@ int64_t vfs::stat(size_t fd, stat_info& info){ auto fs_path = get_fs_path(base_path, fs); //Special handling for root - if(fs_path.empty()){ + if(fs_path.is_root()){ //TODO Add file system support for stat of the root directory info.size = 4096; info.flags = STAT_FLAG_DIRECTORY; @@ -364,7 +362,7 @@ int64_t vfs::read(size_t fd, char* buffer, size_t count, size_t offset){ auto& base_path = scheduler::get_handle(fd); - if(base_path.empty()){ + if(base_path.is_root()){ return -std::ERROR_INVALID_FILE_PATH; } @@ -403,7 +401,7 @@ int64_t vfs::write(size_t fd, const char* buffer, size_t count, size_t offset){ auto& base_path = scheduler::get_handle(fd); - if(base_path.empty()){ + if(base_path.is_root()){ return -std::ERROR_INVALID_FILE_PATH; } @@ -427,7 +425,7 @@ int64_t vfs::clear(size_t fd, size_t count, size_t offset){ auto& base_path = scheduler::get_handle(fd); - if(base_path.empty()){ + if(base_path.is_root()){ return -std::ERROR_INVALID_FILE_PATH; } @@ -466,7 +464,7 @@ int64_t vfs::truncate(size_t fd, size_t size){ auto& base_path = scheduler::get_handle(fd); - if(base_path.empty()){ + if(base_path.is_root()){ return -std::ERROR_INVALID_FILE_PATH; } @@ -561,7 +559,7 @@ int64_t vfs::mounts(char* buffer, size_t size){ size_t total_size = 0; for(auto& mp : mount_point_list){ - total_size += 4 * sizeof(size_t) + 3 + mp.device.size() + mp.mount_point.size() + partition_type_to_string(mp.fs_type).size(); + total_size += 4 * sizeof(size_t) + 3 + mp.device.size() + mp.mount_point.string().size() + partition_type_to_string(mp.fs_type).size(); } if(size < total_size){ @@ -577,12 +575,12 @@ int64_t vfs::mounts(char* buffer, size_t size){ auto fs_type = partition_type_to_string(mp.fs_type); - entry->length_mp = mp.mount_point.size(); + entry->length_mp = mp.mount_point.string().size(); entry->length_dev = mp.device.size(); entry->length_type = fs_type.size(); if(i + 1 < mount_point_list.size()){ - entry->offset_next = 4 * sizeof(size_t) + 3 + mp.device.size() + mp.mount_point.size() + fs_type.size(); + entry->offset_next = 4 * sizeof(size_t) + 3 + mp.device.size() + mp.mount_point.string().size() + fs_type.size(); position += entry->offset_next; } else { entry->offset_next = 0; @@ -591,8 +589,9 @@ int64_t vfs::mounts(char* buffer, size_t size){ char* name_buffer = &(entry->name); size_t str_pos = 0; - for(size_t j = 0; j < mp.mount_point.size(); ++j){ - name_buffer[str_pos++] = mp.mount_point[j]; + auto mount_point = mp.mount_point.string(); + for(size_t j = 0; j < mount_point.size(); ++j){ + name_buffer[str_pos++] = mount_point[j]; } name_buffer[str_pos++] = '\0'; for(size_t j = 0; j < mp.device.size(); ++j){ diff --git a/kernel/src/virtual_allocator.cpp b/kernel/src/virtual_allocator.cpp index f62a5926..4dd7fe46 100644 --- a/kernel/src/virtual_allocator.cpp +++ b/kernel/src/virtual_allocator.cpp @@ -85,9 +85,9 @@ void virtual_allocator::init(){ } void virtual_allocator::finalize(){ - sysfs::set_dynamic_value("/sys/", "/memory/virtual/available", &sysfs_available); - sysfs::set_dynamic_value("/sys/", "/memory/virtual/free", &sysfs_free); - sysfs::set_dynamic_value("/sys/", "/memory/virtual/allocated", &sysfs_allocated); + sysfs::set_dynamic_value(path("/sys/"), path("/memory/virtual/available"), &sysfs_available); + sysfs::set_dynamic_value(path("/sys/"), path("/memory/virtual/free"), &sysfs_free); + sysfs::set_dynamic_value(path("/sys/"), path("/memory/virtual/allocated"), &sysfs_allocated); } size_t virtual_allocator::allocate(size_t pages){ diff --git a/programs/tsh/src/main.cpp b/programs/tsh/src/main.cpp index 1ca04e57..31f87662 100644 --- a/programs/tsh/src/main.cpp +++ b/programs/tsh/src/main.cpp @@ -85,19 +85,13 @@ void cd_command(const std::vector& params){ if(!(info->flags & STAT_FLAG_DIRECTORY)){ print_line("cat: error: Is not a directory"); } else { - auto cwd = current_working_directory(); - if(path[0] == '/'){ - cwd = "/"; - } + set_current_working_directory(path); + } else { + auto cwd = current_working_directory(); - auto parts = std::split(path, '/'); - for(auto& part : parts){ - cwd += part; - cwd += '/'; + set_current_working_directory(cwd + "/" + path); } - - set_current_working_directory(cwd); } } else { printf("cd: error: %s\n", std::error_message(info.error()));