From f291dd00232b4e9910afd47d0d90a94ba2d461d0 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Wed, 4 Dec 2013 21:36:40 +0100 Subject: [PATCH] Finalize cd in multi level --- kernel/include/disks.hpp | 4 ++-- kernel/include/fat32.hpp | 2 +- kernel/include/vector.hpp | 10 +++++++++- kernel/src/disks.cpp | 8 ++------ kernel/src/fat32.cpp | 34 +++++++++++++++++++++++++--------- kernel/src/shell.cpp | 16 ++++++++++------ 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/kernel/include/disks.hpp b/kernel/include/disks.hpp index e87b0c29..0e4aefe1 100644 --- a/kernel/include/disks.hpp +++ b/kernel/include/disks.hpp @@ -69,8 +69,8 @@ uint64_t free_size(); const disk_descriptor* mounted_disk(); const partition_descriptor* mounted_partition(); -const string& current_directory(); -void set_current_directory(const string& directory = string()); +//TODO It is not a really good practice to directly expose the vector +vector& current_directory(); } diff --git a/kernel/include/fat32.hpp b/kernel/include/fat32.hpp index 6827afff..62264923 100644 --- a/kernel/include/fat32.hpp +++ b/kernel/include/fat32.hpp @@ -9,7 +9,7 @@ namespace fat32 { typedef const disks::disk_descriptor& dd; -vector ls(dd disk, const disks::partition_descriptor& partition, const string& path); +vector ls(dd disk, const disks::partition_descriptor& partition, const vector& path); uint64_t free_size(dd disk, const disks::partition_descriptor& partition); } diff --git a/kernel/include/vector.hpp b/kernel/include/vector.hpp index fb3ce258..5a2818f8 100644 --- a/kernel/include/vector.hpp +++ b/kernel/include/vector.hpp @@ -56,6 +56,10 @@ public: return _size; } + bool empty() const { + return _size; + } + constexpr size_type capacity() const { return _capacity; } @@ -70,7 +74,7 @@ public: //Modifiers - void push_back(value_type& element){ + void push_back(const value_type& element){ if(_capacity == 0){ _capacity = 1; data = new T[_capacity]; @@ -89,6 +93,10 @@ public: data[_size++] = element; } + void clear(){ + _size = 0; + } + //Iterators iterator begin(){ diff --git a/kernel/src/disks.cpp b/kernel/src/disks.cpp index 95ee86ec..2730b271 100644 --- a/kernel/src/disks.cpp +++ b/kernel/src/disks.cpp @@ -45,7 +45,7 @@ const disks::disk_descriptor* _mounted_disk; const disks::partition_descriptor* _mounted_partition; //TODO This should be improved to suppport multi level -string pwd; +vector pwd; } //end of anonymous namespace @@ -228,10 +228,6 @@ uint64_t disks::free_size(){ return fat32::free_size(*_mounted_disk, *_mounted_partition); } -const string& disks::current_directory(){ +const vector& disks::current_directory(){ return pwd; } - -void disks::set_current_directory(const string& directory){ - pwd = directory; -} diff --git a/kernel/src/fat32.cpp b/kernel/src/fat32.cpp index 33cd4f55..e9233819 100644 --- a/kernel/src/fat32.cpp +++ b/kernel/src/fat32.cpp @@ -186,7 +186,7 @@ bool filename_equals(char* name, const string& path){ } //end of anonymous namespace -vector fat32::ls(dd disk, const disks::partition_descriptor& partition, const string& path){ +vector fat32::ls(dd disk, const disks::partition_descriptor& partition, const vector& path){ if(cached_disk != disk.uuid || cached_partition != partition.uuid){ partition_start = partition.start; @@ -204,22 +204,38 @@ vector fat32::ls(dd disk, const disks::partition_descriptor& partit auto cluster_addr = cluster_lba(fat_bs->root_directory_cluster_start); - unique_heap_array root_cluster(16 * fat_bs->sectors_per_cluster); + unique_heap_array current_cluster(16 * fat_bs->sectors_per_cluster); - if(read_sectors(disk, cluster_addr, fat_bs->sectors_per_cluster, root_cluster.get())){ - if(path.empty()){ - return files(root_cluster); - } else { - for(auto& entry : root_cluster){ + k_print_line(path.size()); + + if(read_sectors(disk, cluster_addr, fat_bs->sectors_per_cluster, current_cluster.get())){ + for(auto& p : path){ + bool found = false; + + for(auto& entry : current_cluster){ if(entry_exists(entry) && !is_long_name(entry) && entry.attrib & 0x10){ //entry.name is not a real c_string, cannot be compared //directly - if(filename_equals(entry.name, path)){ - return files(disk, entry.cluster_low + (entry.cluster_high << 16)); + if(filename_equals(entry.name, p)){ + unique_heap_array cluster(16 * fat_bs->sectors_per_cluster); + + if(read_sectors(disk, cluster_lba(entry.cluster_low + (entry.cluster_high << 16)), + fat_bs->sectors_per_cluster, cluster.get())){ + current_cluster = move(cluster); + found = true; + } else { + return {}; + } } } } + + if(!found){ + return {}; + } } + + return files(current_cluster); } return {}; diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index 0a7ca1ca..6d7d7ad1 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -475,18 +475,22 @@ void free_command(const vector&){ void pwd_command(const vector&){ auto& cd = disks::current_directory(); - if(cd.empty()){ - k_print_line("/"); - } else { - k_printf("/%s\n", cd.c_str()); + k_print('/'); + + for(auto& p : cd){ + k_print(p); + k_print('/'); } + + k_print_line(); } void cd_command(const vector& params){ + //If there are no params, go to / if(params.size() == 1){ - disks::set_current_directory(); + disks::current_directory().clear(); } else { - disks::set_current_directory(params[1]); + disks::current_directory().push_back(params[1]); } }