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 { struct devfs_file_system : vfs::file_system {
private: private:
std::string mount_point; path mount_point;
public: public:
devfs_file_system(std::string mount_point); devfs_file_system(path mount_point);
~devfs_file_system(); ~devfs_file_system();
size_t statfs(statfs_info& file); 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 { struct fat32_file_system : vfs::file_system {
private: private:
std::string mount_point; path mount_point;
std::string device; std::string device;
fat_bs_t* fat_bs = nullptr; fat_bs_t* fat_bs = nullptr;
fat_is_t* fat_is = nullptr; fat_is_t* fat_is = nullptr;
public: public:
fat32_file_system(std::string mount_point, std::string device); fat32_file_system(path mount_point, std::string device);
~fat32_file_system(); ~fat32_file_system();
void init(); void init();

View File

@ -20,10 +20,10 @@ namespace procfs {
struct procfs_file_system : vfs::file_system { struct procfs_file_system : vfs::file_system {
private: private:
std::string mount_point; path mount_point;
public: public:
procfs_file_system(std::string mount_point); procfs_file_system(path mount_point);
~procfs_file_system(); ~procfs_file_system();
size_t statfs(statfs_info& file); size_t statfs(statfs_info& file);

View File

@ -18,10 +18,10 @@ namespace sysfs {
struct sysfs_file_system : vfs::file_system { struct sysfs_file_system : vfs::file_system {
private: private:
std::string mount_point; path mount_point;
public: public:
sysfs_file_system(std::string mount_point); sysfs_file_system(path mount_point);
~sysfs_file_system(); ~sysfs_file_system();
size_t statfs(statfs_info& file); size_t statfs(statfs_info& file);
@ -38,12 +38,12 @@ public:
typedef std::string (*dynamic_fun_t)(); 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_constant_value(const path& mount_point, const path& file_path, const std::string& value);
void set_dynamic_value(const std::string& mount_point, const std::string& path, dynamic_fun_t fun); 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_value(const path& mount_point, const path& file_path);
void delete_folder(const std::string& mount_point, const std::string& path); void delete_folder(const path& mount_point, const path& file_path);
} } //end of namespace sysfs
#endif #endif

View File

@ -20,6 +20,7 @@ struct path {
path(); path();
path(const std::string& path); path(const std::string& path);
path(const path& base_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(const path&) = default;
path(path&&) = default; path(path&&) = default;
@ -38,8 +39,13 @@ struct path {
bool empty() const; bool empty() const;
bool is_root() const; bool is_root() const;
bool is_valid() const; bool is_valid() const;
bool is_sub_root() const;
size_t size() const; size_t size() const;
std::string base_name() 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 // Accessors to sub parts
const std::string& name(size_t i) const; const std::string& name(size_t i) const;
@ -47,13 +53,22 @@ struct path {
// Decomposition functions // Decomposition functions
path sub_path(size_t i) const; path sub_path(size_t i) const;
path branch_path() const;
// Iterators // Iterators
iterator begin() const ; iterator begin() const ;
iterator end() const ; iterator end() const ;
// relational operators
bool operator==(const path& p) const;
bool operator!=(const path& p) const;
private: private:
std::vector<std::string> names; 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 #endif

View File

@ -108,11 +108,9 @@ void disks::detect_disks(){
} }
} }
std::string path = "/ata/" + name; 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("/sys/", path + "/model", descriptor.model); sysfs::set_constant_value(path("/sys"), path("/ata") / name / "firmware", descriptor.firmware);
sysfs::set_constant_value("/sys/", path + "/serial", descriptor.serial);
sysfs::set_constant_value("/sys/", path + "/firmware", descriptor.firmware);
++number_of_disks; ++number_of_disks;
} }

View File

@ -29,18 +29,18 @@ struct device {
}; };
struct device_list { struct device_list {
std::string name; path mount_point;
std::vector<device> devices; std::vector<device> devices;
device_list(){}; device_list(){};
device_list(std::string name) : name(name){} device_list(path mp) : mount_point(mp){}
}; };
std::vector<device_list> devices; std::vector<device_list> devices;
} //end of anonymous namespace } //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 //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){ 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.file_name = "/";
f.directory = true; f.directory = true;
f.hidden = false; 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 //No subfolder support
if(file_path.size() > 1){ if(file_path.size() > 2){
return std::ERROR_NOT_EXISTS; return std::ERROR_NOT_EXISTS;
} }
for(auto& device_list : devices){ for(auto& device_list : devices){
if(device_list.name == mount_point){ if(device_list.mount_point == mount_point){
for(auto& device : device_list.devices){ for(auto& device : device_list.devices){
if(device.name == file_path.base_name()){ if(device.name == file_path.base_name()){
f.file_name = device.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){ 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 //Cannot access the root for reading
if(file_path.empty()){ if(file_path.is_root()){
return std::ERROR_PERMISSION_DENIED; return std::ERROR_PERMISSION_DENIED;
} }
for(auto& device_list : devices){ for(auto& device_list : devices){
if(device_list.name == mount_point){ if(device_list.mount_point == mount_point){
for(auto& device : device_list.devices){ for(auto& device : device_list.devices){
if(device.name == file_path.base_name()){ if(device.name == file_path.base_name()){
if(!device.driver){ 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){ 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 //Cannot access the root for writing
if(file_path.empty()){ if(file_path.is_root()){
return std::ERROR_PERMISSION_DENIED; return std::ERROR_PERMISSION_DENIED;
} }
for(auto& device_list : devices){ for(auto& device_list : devices){
if(device_list.name == mount_point){ if(device_list.mount_point == mount_point){
for(auto& device : device_list.devices){ for(auto& device : device_list.devices){
if(device.name == file_path.base_name()){ if(device.name == file_path.base_name()){
if(!device.driver){ 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){ 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 //Cannot access the root for writing
if(file_path.empty()){ if(file_path.is_root()){
return std::ERROR_PERMISSION_DENIED; return std::ERROR_PERMISSION_DENIED;
} }
for(auto& device_list : devices){ for(auto& device_list : devices){
if(device_list.name == mount_point){ if(device_list.mount_point == mount_point){
for(auto& device : device_list.devices){ for(auto& device : device_list.devices){
if(device.name == file_path.base_name()){ if(device.name == file_path.base_name()){
if(!device.driver){ 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){ size_t devfs::devfs_file_system::ls(const path& file_path, std::vector<vfs::file>& contents){
//No subfolder support //No subfolder support
if(file_path.size() > 0){ if(file_path.size() > 1){
return std::ERROR_NOT_EXISTS; return std::ERROR_NOT_EXISTS;
} }
for(auto& device_list : devices){ for(auto& device_list : devices){
if(device_list.name == mount_point){ if(device_list.mount_point == mount_point){
for(auto& device : device_list.devices){ for(auto& device : device_list.devices){
vfs::file f; vfs::file f;
f.file_name = device.name; 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){ 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){ 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); device_list.devices.emplace_back(name, type, driver, data);
return; 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){ void devfs::deregister_device(const std::string& mp, const std::string& name){
for(auto& device_list : devices){ 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){ for(size_t i = 0; i < device_list.devices.size(); ++i){
if(device_list.devices[i].name == name){ if(device_list.devices[i].name == name){
device_list.devices.erase(i); 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){ 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; return std::ERROR_INVALID_DEVICE;
} }
// TODO store the mount point with the slash
std::string mp("/" + device_name[0] + "/");
for(auto& device_list : devices){ 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){ 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){ if(device.type == device_type::BLOCK_DEVICE){
size = device.driver->size(device.data); 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 } //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 //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){ 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; 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); 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]; auto& p = file_path[i];
bool found = false; bool found = false;

View File

@ -61,7 +61,7 @@ void procfs::set_pcb(const scheduler::process_control_t* pcb_ptr){
pcb = 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.reserve(7);
standard_contents.emplace_back("pid", false, false, false, 0); standard_contents.emplace_back("pid", false, false, false, 0);
standard_contents.emplace_back("ppid", 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){ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f){
// Access the root folder // Access the root folder
if(file_path.empty()){ if(file_path.is_root()){
f.file_name = "/"; f.file_name = "/";
f.directory = true; f.directory = true;
f.hidden = false; f.hidden = false;
@ -88,7 +88,7 @@ size_t procfs::procfs_file_system::get_file(const path& file_path, vfs::file& f)
return 0; return 0;
} }
auto i = atoui(file_path[0]); auto i = atoui(file_path[1]);
// Check the pid folder // Check the pid folder
if(i >= scheduler::MAX_PROCESS){ 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 // Access a pid folder
if(file_path.size() == 1){ if(file_path.size() == 2){
f.file_name = file_path[0]; f.file_name = file_path[1];
f.directory = true; f.directory = true;
f.hidden = false; f.hidden = false;
f.system = 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 // Access a file directly
if(file_path.size() == 2){ if(file_path.size() == 3){
auto value = get_value(i, file_path[1]); auto value = get_value(i, file_path[2]);
if(value.size()){ if(value.size()){
f.file_name = file_path[1]; f.file_name = file_path[2];
f.directory = false; f.directory = false;
f.hidden = false; f.hidden = false;
f.system = 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){ 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 //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; return std::ERROR_PERMISSION_DENIED;
} }
if(file_path.size() == 2){ if(file_path.size() == 3){
auto i = atoui(file_path[0]); auto i = atoui(file_path[1]);
if(i >= scheduler::MAX_PROCESS){ if(i >= scheduler::MAX_PROCESS){
return std::ERROR_NOT_EXISTS; 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; return std::ERROR_NOT_EXISTS;
} }
auto value = get_value(i, file_path[1]); auto value = get_value(i, file_path[2]);
if(value.size()){ if(value.size()){
return ::read(value, buffer, count, offset, read); 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){ 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.is_root()){
if(file_path.size() == 0){
for(size_t i = 0; i < scheduler::MAX_PROCESS; ++i){ for(size_t i = 0; i < scheduler::MAX_PROCESS; ++i){
auto& process = pcb[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; return 0;
} }
if(file_path.size() == 1){ if(file_path.size() == 2){
contents = standard_contents; contents = standard_contents;
return 0; return 0;
} }

View File

@ -14,6 +14,7 @@
#include "console.hpp" #include "console.hpp"
#include "rtc.hpp" #include "rtc.hpp"
#include "assert.hpp"
namespace { namespace {
@ -54,14 +55,16 @@ struct sys_folder {
std::vector<sys_folder> root_folders; 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){ for(auto& sys_folder : root_folders){
if(sys_folder.name == mount_point){ if(sys_folder.name == mount_point.sub_root_name()){
return sys_folder; return sys_folder;
} }
} }
root_folders.emplace_back(mount_point); root_folders.emplace_back(mount_point.sub_root_name());
return root_folders.back(); return root_folders.back();
} }
@ -227,7 +230,7 @@ void delete_folder(sys_folder& folder, const std::string& name){
} //end of anonymous namespace } //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 //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){ size_t sysfs::sysfs_file_system::get_file(const path& file_path, vfs::file& f){
auto& root_folder = find_root_folder(mount_point); auto& root_folder = find_root_folder(mount_point);
if(file_path.empty()){ if(file_path.is_root()){
f.file_name = "/"; f.file_name = "/";
f.directory = true; f.directory = true;
f.hidden = false; 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; f.size = 0;
return 0; return 0;
} else if(file_path.size() == 1){ } else if(file_path.size() == 2){
return ::get_file(root_folder, file_path, f); return ::get_file(root_folder, file_path, f);
} else { } else {
if(exists_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, 0, file_path.size() - 1); auto& folder = find_folder(root_folder, file_path, 1, file_path.size() - 1);
return ::get_file(folder, file_path, f); 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){ 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); auto& root_folder = find_root_folder(mount_point);
if(file_path.empty()){ if(file_path.is_root()){
return std::ERROR_DIRECTORY; 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); return ::read(root_folder, file_path, buffer, count, offset, read);
} else { } else {
if(exists_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, 0, 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); 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){ size_t sysfs::sysfs_file_system::ls(const path& file_path, std::vector<vfs::file>& contents){
auto& root_folder = find_root_folder(mount_point); auto& root_folder = find_root_folder(mount_point);
if(file_path.empty()){ if(file_path.is_root()){
return ::ls(root_folder, contents); return ::ls(root_folder, contents);
} else { } else {
if(exists_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, 0, file_path.size()); auto& folder = find_folder(root_folder, file_path, 1, file_path.size());
return ::ls(folder, contents); return ::ls(folder, contents);
} }
@ -324,55 +327,47 @@ size_t sysfs::sysfs_file_system::statfs(statfs_info& file){
return 0; 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); auto& root_folder = find_root_folder(mount_point);
path file_path(p); if(file_path.size() == 2){
if(file_path.size() == 1){
::set_value(root_folder, file_path.base_name(), value); ::set_value(root_folder, file_path.base_name(), value);
} else { } 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); ::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); auto& root_folder = find_root_folder(mount_point);
path file_path(p); if(file_path.size() == 2){
if(file_path.size() == 1){
::set_value(root_folder, file_path.base_name(), fun); ::set_value(root_folder, file_path.base_name(), fun);
} else { } 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); ::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); auto& root_folder = find_root_folder(mount_point);
path file_path(p); if(file_path.size() == 2){
if(file_path.size() == 1){
::delete_value(root_folder, file_path.base_name()); ::delete_value(root_folder, file_path.base_name());
} else { } 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()); ::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); auto& root_folder = find_root_folder(mount_point);
path file_path(p); if(file_path.size() == 2){
if(file_path.size() == 1){
::delete_folder(root_folder, file_path.base_name()); ::delete_folder(root_folder, file_path.base_name());
} else { } 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()); ::delete_folder(folder, file_path.base_name());
} }

View File

@ -332,9 +332,9 @@ void kalloc::init(){
} }
void kalloc::finalize(){ void kalloc::finalize(){
sysfs::set_dynamic_value("/sys/", "/memory/dynamic/free", &sysfs_free); sysfs::set_dynamic_value(path("/sys"), path("/memory/dynamic/free"), &sysfs_free);
sysfs::set_dynamic_value("/sys/", "/memory/dynamic/used", &sysfs_used); sysfs::set_dynamic_value(path("/sys"), path("/memory/dynamic/used"), &sysfs_used);
sysfs::set_dynamic_value("/sys/", "/memory/dynamic/allocated", &sysfs_allocated); sysfs::set_dynamic_value(path("/sys"), path("/memory/dynamic/allocated"), &sysfs_allocated);
} }
void* kalloc::k_malloc(uint64_t bytes){ 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 //Only install system calls when everything else is ready
install_system_calls(); install_system_calls();
sysfs::set_constant_value("/sys/", "version", "0.1"); sysfs::set_constant_value(path("/sys"), path("/version"), "0.1");
sysfs::set_constant_value("/sys/", "author", "Baptiste Wicht"); sysfs::set_constant_value(path("/sys"), path("/author"), "Baptiste Wicht");
// Initialize the scheduler // Initialize the scheduler
scheduler::init(); scheduler::init();

View File

@ -84,13 +84,13 @@ void network::init(){
rtl8139::init_driver(interface, pci_device); 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(path("/sys"), p / "name", interface.name);
sysfs::set_constant_value("/sys/", path + "/driver", interface.driver); sysfs::set_constant_value(path("/sys"), p / "driver", interface.driver);
sysfs::set_constant_value("/sys/", path + "/enabled", interface.enabled ? "true" : "false"); sysfs::set_constant_value(path("/sys"), p / "enabled", interface.enabled ? "true" : "false");
sysfs::set_constant_value("/sys/", path + "/pci_device", std::to_string(i)); sysfs::set_constant_value(path("/sys"), p / "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 / "mac", std::to_string(interface.mac_address));
++index; ++index;
} }

View File

@ -266,11 +266,11 @@ void paging::init(){
} }
void paging::finalize(){ void paging::finalize(){
sysfs::set_constant_value("/sys/", "/paging/page_size", std::to_string(paging::PAGE_SIZE)); sysfs::set_constant_value(path("/sys"), path("/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(path("/sys"), path("/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(path("/sys"), path("/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(path("/sys"), path("/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/physical_size"), std::to_string(paging::physical_memory_pages * paging::PAGE_SIZE));
} }
size_t paging::pages(size_t size){ size_t paging::pages(size_t size){

View File

@ -7,21 +7,30 @@
#include "vfs/path.hpp" #include "vfs/path.hpp"
#include "assert.hpp"
path::path(){ path::path(){
//Nothing to init //Nothing to init
} }
path::path(const std::string& path){ path::path(const std::string& path){
if(path[0] == '/'){
names.push_back("/");
}
auto parts = std::split(path, '/'); auto parts = std::split(path, '/');
names.reserve(parts.size()); names.reserve(names.size() + parts.size());
for(auto& part : parts){ for(auto& part : parts){
names.push_back(part); names.push_back(part);
} }
} }
path::path(const path& base_path, const std::string& path){ path::path(const path& base_path, const std::string& p){
auto parts = std::split(path, '/'); thor_assert(p.empty() || p[0] != '/', "Impossible to add absolute path to another path");
names.reserve(base_path.size() + parts.size());
auto parts = std::split(p, '/');
names.reserve(names.size() + base_path.size() + parts.size());
for(auto& part : base_path){ for(auto& part : base_path){
names.push_back(part); 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 path::path(const path& base_path, const path& p){
std::string path::string() const { thor_assert(p.is_relative(), "Impossible to add absolute path to another path");
std::string path("/");
for(auto& part : names){ names.reserve(names.size() + base_path.size() + p.size());
path += part;
path += '/'; 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 { const std::vector<std::string>& path::vec() const {
@ -58,11 +91,15 @@ bool path::empty() const {
} }
bool path::is_root() const { bool path::is_root() const {
return names.empty(); return names.size() == 1 && names[0] == "/";
} }
bool path::is_valid() const { 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 { 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 { const std::string& path::name(size_t i) const {
return names[i]; return names[i];
} }
@ -92,6 +153,25 @@ path path::sub_path(size_t i) const {
return p; 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 { path::iterator path::begin() const {
return names.begin(); return names.begin();
} }
@ -99,3 +179,23 @@ path::iterator path::begin() const {
path::iterator path::end() const { path::iterator path::end() const {
return names.end(); 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; 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)); auto p = path("/pci") / pci_name;
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(path("/sys"), p / "vendor", std::to_string(vendor_id));
sysfs::set_constant_value("/sys/", path + "/subclass", std::to_string(sub_class)); 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) { void check_device(uint8_t bus, uint8_t device) {

View File

@ -164,22 +164,22 @@ void physical_allocator::init(){
} }
void physical_allocator::finalize(){ void physical_allocator::finalize(){
sysfs::set_dynamic_value("/sys/", "/memory/physical/available", &sysfs_available); sysfs::set_dynamic_value(path("/sys"), path("/memory/physical/available"), &sysfs_available);
sysfs::set_dynamic_value("/sys/", "/memory/physical/free", &sysfs_free); sysfs::set_dynamic_value(path("/sys"), path("/memory/physical/free"), &sysfs_free);
sysfs::set_dynamic_value("/sys/", "/memory/physical/allocated", &sysfs_allocated); sysfs::set_dynamic_value(path("/sys"), path("/memory/physical/allocated"), &sysfs_allocated);
// Publish the e820 map // Publish the e820 map
auto entries = e820::mmap_entry_count(); 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){ for(size_t i = 0; i < entries; ++i){
auto& entry = e820::mmap_entry(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(path("/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(path("/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 / "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_start = 0;
process.process.brk_end = 0; process.process.brk_end = 0;
// By default, a process is working in root
process.working_directory = path("/");
return process.process; return process.process;
} }

View File

@ -54,7 +54,7 @@ void timer::install(){
suspend_boot(); suspend_boot();
} }
sysfs::set_dynamic_value("/sys/", "uptime", &sysfs_uptime); sysfs::set_dynamic_value(path("/sys"), path("/uptime"), &sysfs_uptime);
} }
void timer::tick(){ void timer::tick(){

View File

@ -80,9 +80,9 @@ bool vesa::init(){
screen = reinterpret_cast<uint32_t*>(virt); screen = reinterpret_cast<uint32_t*>(virt);
sysfs::set_constant_value("/sys/", "/vesa/enabled", "true"); sysfs::set_constant_value(path("/sys"), path("/vesa/enabled"), "true");
sysfs::set_constant_value("/sys/", "/vesa/resolution/width", std::to_string(block.width)); sysfs::set_constant_value(path("/sys"), path("/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/resolution/height"), std::to_string(block.height));
return true; return true;
} }

View File

@ -26,23 +26,22 @@
#include "console.hpp" #include "console.hpp"
#include "logging.hpp" #include "logging.hpp"
#include "assert.hpp"
namespace { namespace {
struct mounted_fs { struct mounted_fs {
vfs::partition_type fs_type; vfs::partition_type fs_type;
std::string device; std::string device;
std::string mount_point; path mount_point;
vfs::file_system* file_system; vfs::file_system* file_system;
std::vector<std::string> mp_vec;
mounted_fs() = default; 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) 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){ path get_path(const char* file_path){
if(file_path[0] != '/'){ path p(file_path);
return {scheduler::get_working_directory(), file_path};
} else { if(p.is_relative()){
return {file_path}; return scheduler::get_working_directory() / p;
} }
return p;
} }
mounted_fs& get_fs(const path& base_path){ 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()){ if(base_path.is_root()){
for(auto& mp : mount_point_list){ for(auto& mp : mount_point_list){
if(mp.mp_vec.empty()){ if(mp.mount_point.is_root()){
return mp; return mp;
} }
} }
@ -106,15 +107,15 @@ mounted_fs& get_fs(const path& base_path){
auto& mp = mount_point_list[i]; auto& mp = mount_point_list[i];
bool match = true; bool match = true;
for(size_t j = 0; j < mp.mp_vec.size() && j < base_path.size() ; ++j){ for(size_t j = 0; j < mp.mount_point.size() && j < base_path.size() ; ++j){
if(mp.mp_vec[j] != base_path[j]){ if(mp.mount_point[j] != base_path[j]){
match = false; match = false;
break; break;
} }
} }
if(match && mp.mp_vec.size() > best){ if(match && mp.mount_point.size() > best){
best = mp.mp_vec.size(); best = mp.mount_point.size();
best_match = i; 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){ 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){ switch(type){
case vfs::partition_type::FAT32: case vfs::partition_type::FAT32:
return new fat32::fat32_file_system(mount_point, device); 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& mp_path = scheduler::get_handle(mp_fd);
auto& dev_path = scheduler::get_handle(dev_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){ for(auto& m : mount_point_list){
if(m.mount_point == mp){ if(m.mount_point == mp_path){
return -std::ERROR_ALREADY_MOUNTED; 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){ if(!fs){
return -std::ERROR_INVALID_FILE_SYSTEM; 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(); 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; return 0;
} }
int64_t vfs::mount(partition_type type, const char* mount_point, const char* device){ 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){ if(!fs){
return -std::ERROR_INVALID_FILE_SYSTEM; 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; 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 = get_fs(base_path);
auto fs_path = get_fs_path(base_path, fs); 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 //Special handling for opening the root
if(fs_path.is_root()){ if(fs_path.is_root()){
return scheduler::register_new_handle(base_path); 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); auto fs_path = get_fs_path(base_path, fs);
//Special handling for root //Special handling for root
if(fs_path.empty()){ if(fs_path.is_root()){
//TODO Add file system support for stat of the root directory //TODO Add file system support for stat of the root directory
info.size = 4096; info.size = 4096;
info.flags = STAT_FLAG_DIRECTORY; 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); auto& base_path = scheduler::get_handle(fd);
if(base_path.empty()){ if(base_path.is_root()){
return -std::ERROR_INVALID_FILE_PATH; 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); auto& base_path = scheduler::get_handle(fd);
if(base_path.empty()){ if(base_path.is_root()){
return -std::ERROR_INVALID_FILE_PATH; 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); auto& base_path = scheduler::get_handle(fd);
if(base_path.empty()){ if(base_path.is_root()){
return -std::ERROR_INVALID_FILE_PATH; 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); auto& base_path = scheduler::get_handle(fd);
if(base_path.empty()){ if(base_path.is_root()){
return -std::ERROR_INVALID_FILE_PATH; return -std::ERROR_INVALID_FILE_PATH;
} }
@ -561,7 +559,7 @@ int64_t vfs::mounts(char* buffer, size_t size){
size_t total_size = 0; size_t total_size = 0;
for(auto& mp : mount_point_list){ 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){ 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); 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_dev = mp.device.size();
entry->length_type = fs_type.size(); entry->length_type = fs_type.size();
if(i + 1 < mount_point_list.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; position += entry->offset_next;
} else { } else {
entry->offset_next = 0; entry->offset_next = 0;
@ -591,8 +589,9 @@ int64_t vfs::mounts(char* buffer, size_t size){
char* name_buffer = &(entry->name); char* name_buffer = &(entry->name);
size_t str_pos = 0; size_t str_pos = 0;
for(size_t j = 0; j < mp.mount_point.size(); ++j){ auto mount_point = mp.mount_point.string();
name_buffer[str_pos++] = mp.mount_point[j]; for(size_t j = 0; j < mount_point.size(); ++j){
name_buffer[str_pos++] = mount_point[j];
} }
name_buffer[str_pos++] = '\0'; name_buffer[str_pos++] = '\0';
for(size_t j = 0; j < mp.device.size(); ++j){ for(size_t j = 0; j < mp.device.size(); ++j){

View File

@ -85,9 +85,9 @@ void virtual_allocator::init(){
} }
void virtual_allocator::finalize(){ void virtual_allocator::finalize(){
sysfs::set_dynamic_value("/sys/", "/memory/virtual/available", &sysfs_available); sysfs::set_dynamic_value(path("/sys/"), path("/memory/virtual/available"), &sysfs_available);
sysfs::set_dynamic_value("/sys/", "/memory/virtual/free", &sysfs_free); sysfs::set_dynamic_value(path("/sys/"), path("/memory/virtual/free"), &sysfs_free);
sysfs::set_dynamic_value("/sys/", "/memory/virtual/allocated", &sysfs_allocated); sysfs::set_dynamic_value(path("/sys/"), path("/memory/virtual/allocated"), &sysfs_allocated);
} }
size_t virtual_allocator::allocate(size_t pages){ 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)){ if(!(info->flags & STAT_FLAG_DIRECTORY)){
print_line("cat: error: Is not a directory"); print_line("cat: error: Is not a directory");
} else { } else {
auto cwd = current_working_directory();
if(path[0] == '/'){ if(path[0] == '/'){
cwd = "/"; set_current_working_directory(path);
} } else {
auto cwd = current_working_directory();
auto parts = std::split(path, '/'); set_current_working_directory(cwd + "/" + path);
for(auto& part : parts){
cwd += part;
cwd += '/';
} }
set_current_working_directory(cwd);
} }
} else { } else {
printf("cd: error: %s\n", std::error_message(info.error())); printf("cd: error: %s\n", std::error_message(info.error()));