Better handling of paths

This commit is contained in:
Baptiste Wicht 2016-08-16 21:33:00 +02:00
parent 482473fb02
commit 24cb35c843
23 changed files with 300 additions and 199 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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<std::string> 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

View File

@ -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;
}

View File

@ -29,18 +29,18 @@ struct device {
};
struct device_list {
std::string name;
path mount_point;
std::vector<device> devices;
device_list(){};
device_list(std::string name) : name(name){}
device_list(path mp) : mount_point(mp){}
};
std::vector<device_list> 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<vfs::file>& 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);

View File

@ -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<vfs::file> fat32::fat32_file_system::files(uint32_t cluster_number){
std::pair<bool, uint32_t> 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;

View File

@ -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<vfs::file>& 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<vfs::fi
return 0;
}
if(file_path.size() == 1){
if(file_path.size() == 2){
contents = standard_contents;
return 0;
}

View File

@ -14,6 +14,7 @@
#include "console.hpp"
#include "rtc.hpp"
#include "assert.hpp"
namespace {
@ -54,14 +55,16 @@ struct sys_folder {
std::vector<sys_folder> 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<vfs::file>& 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());
}

View File

@ -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){

View File

@ -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();

View File

@ -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;
}

View File

@ -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){

View File

@ -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<std::string>& 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};
}

View File

@ -86,12 +86,14 @@ std::vector<pci::device_descriptor> 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) {

View File

@ -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));
}
}

View File

@ -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;
}

View File

@ -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(){

View File

@ -80,9 +80,9 @@ bool vesa::init(){
screen = reinterpret_cast<uint32_t*>(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;
}

View File

@ -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<std::string> 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){

View File

@ -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){

View File

@ -85,19 +85,13 @@ void cd_command(const std::vector<std::string>& 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()));