summaryrefslogtreecommitdiff
path: root/kernel/vfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vfile.cpp')
-rw-r--r--kernel/vfile.cpp206
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;
-
- }
-
-}