diff options
Diffstat (limited to 'kernel/vfile.cpp')
-rw-r--r-- | kernel/vfile.cpp | 206 |
1 files changed, 0 insertions, 206 deletions
diff --git a/kernel/vfile.cpp b/kernel/vfile.cpp deleted file mode 100644 index 89c95e6..0000000 --- a/kernel/vfile.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include <hilbert/kernel/vfile.hpp> - -//TODO: handle symlink loops nicely in vfile::get_child, -// vfile::get_children, and lookup_path. - -namespace hilbert::kernel::vfile { - - void canon_path::parent() { - if (segments.count != 0) - --segments.count; - else if (!absolute) - ++parent_count; - } - - void canon_path::rel(const canon_path &r) { - if (r.absolute) { - segments.count = 0; - absolute = true; - parent_count = 0; - } - for (unsigned i = 0; i < r.parent_count; ++i) - parent(); - for (unsigned i = 0; i < r.segments.count; ++i) - segments.add_end(r.segments.buffer[i]); - } - - void canonize_path(const utility::string &name, canon_path &out) { - - out.absolute = false; - out.parent_count = 0; - out.segments.count = 0; - - const char *str = name.buffer; - unsigned len = name.count; - - if (len == 0) - return; - - if (len == 1 && str[0] == '/') { - out.absolute = true; - return; - } - - if (str[0] == '/') { - out.absolute = true; - ++str; - --len; - } - - while (len != 0) { - - unsigned segment_len = utility::find(str, len, '/'); - unsigned to_skip = segment_len == len ? segment_len : segment_len + 1; - - if (segment_len == 0) - ; - - else if (segment_len == 1 && str[0] == '.') - ; - - else if (segment_len == 2 && str[0] == '.' && str[1] == '.') - out.parent(); - - else { - utility::string segment(str, segment_len); - out.segments.add_end(utility::move(segment)); - } - - str += to_skip; - len -= to_skip; - - } - - } - -#define RET_NOT_SUC(expr) \ - { \ - storage::fs_result _result = expr; \ - if (_result != storage::fs_result::success) \ - return _result; \ - } - - storage::fs_result vfile::follow_symlinks(vfile &out) const { - - if (dir_entry.type != storage::file_type::symlink) { - out = *this; - return storage::fs_result::success; - } - - canon_path target_path; - canonize_path(dir_entry.target, target_path); - canon_path full_path = path; - full_path.parent(); - full_path.rel(target_path); - - vfile next; - RET_NOT_SUC(lookup_path(full_path, next, false)) - - next.path = path; - return next.follow_symlinks(out); - - } - - storage::fs_result vfile::get_child( - vfile &out, const utility::string &name - ) const { - - storage::dir_entry entry; - storage::directory_iter_t iter; - - RET_NOT_SUC(bd->mounted_as->get_first_child(dir_entry.node, entry, iter)) - - while (true) { - - if (entry.name == name) { - - vfile vf; - vf.bd = bd; - vf.dir_entry = utility::move(entry); - vf.path = path; - vf.path.segments.add_end(name); - out = utility::move(vf); - return storage::fs_result::success; - - } - - RET_NOT_SUC(bd->mounted_as->get_next_child(dir_entry.node, entry, iter)) - - } - - } - - storage::fs_result vfile::get_children(utility::vector<vfile> &out) const { - - storage::dir_entry entry; - storage::directory_iter_t iter; - - storage::fs_result result = - bd->mounted_as->get_first_child(dir_entry.node, entry, iter); - if (result == storage::fs_result::does_not_exist) - return storage::fs_result::success; - else if (result != storage::fs_result::success) - return result; - - while (true) { - - vfile vf; - vf.bd = bd; - vf.path = path; - vf.path.segments.add_end(entry.name); - vf.dir_entry = utility::move(entry); - out.add_end(utility::move(vf)); - - result = bd->mounted_as->get_next_child(dir_entry.node, entry, iter); - if (result == storage::fs_result::does_not_exist) - return storage::fs_result::success; - else if (result != storage::fs_result::success) - return result; - - } - - } - - storage::fs_result vfile::read_file( - uint64_t start, uint64_t length, void *into - ) const { - return bd->mounted_as->read_bytes_from_file( - dir_entry.node, start, length, into); - } - - //TODO: see comment at top of vfile.hpp. - static const vfile *root; - - void set_root(const vfile &root) { - kernel::vfile::root = new vfile(root); - } - - storage::fs_result lookup_path( - const canon_path &path, vfile &out, bool follow_final_symlink - ) { - - //assume path is absolute. - - out = *root; - for (unsigned i = 0; i < path.segments.count; ++i) { - - vfile result; - RET_NOT_SUC(out.follow_symlinks(result)) - out = utility::move(result); - - RET_NOT_SUC(out.get_child(result, path.segments.buffer[i])) - out = utility::move(result); - - } - - if (follow_final_symlink) { - vfile result; - RET_NOT_SUC(out.follow_symlinks(result)) - out = utility::move(result); - } - - return storage::fs_result::success; - - } - -} |