summaryrefslogtreecommitdiff
path: root/include/hilbert/kernel/vfile.hpp
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-01-15 15:44:20 -0500
committerBenji Dial <benji@benjidial.net>2024-01-15 15:44:20 -0500
commitc9a1266d219a83882735a3a8304f3824e0219cdb (patch)
treefea71a0b5b0de8f3a8962dc6ed417273f231e2a9 /include/hilbert/kernel/vfile.hpp
parent7c6a18d77a81f232ad2e1d3a311bb21ea8f1f5b4 (diff)
downloadhilbert-os-c9a1266d219a83882735a3a8304f3824e0219cdb.tar.gz
redo application paging and system calls, rename mercury to hilbert
Diffstat (limited to 'include/hilbert/kernel/vfile.hpp')
-rw-r--r--include/hilbert/kernel/vfile.hpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/include/hilbert/kernel/vfile.hpp b/include/hilbert/kernel/vfile.hpp
new file mode 100644
index 0000000..086b6ab
--- /dev/null
+++ b/include/hilbert/kernel/vfile.hpp
@@ -0,0 +1,67 @@
+#ifndef HILBERT_KERNEL_VFILE_HPP
+#define HILBERT_KERNEL_VFILE_HPP
+
+#include <hilbert/kernel/storage.hpp>
+#include <hilbert/kernel/utility.hpp>
+
+//TODO: mounts points.
+//maybe a two-way map between mount points and targets? one mount point per
+//target and vice versa. only directories may be mount points, and only file
+//system roots (which must be directories) may be targets.
+
+namespace hilbert::kernel::vfile {
+
+ //a canon path contains no . or empty directory names, and
+ //contains no .. except for at the start of a relative path.
+ struct canon_path {
+
+ bool absolute;
+ unsigned parent_count;
+ utility::vector<utility::string> segments;
+
+ canon_path() : absolute(false), parent_count(0), segments(8) {}
+
+ void parent();
+ void rel(const canon_path &r);
+
+ utility::string to_string(bool trailing_slash) const;
+
+ };
+
+ void canonize_path(const utility::string &name, canon_path &out);
+
+ struct vfile {
+
+ //on followed symlinks, path is the source of the symlink and the
+ //rest of these are the target. in any case, path should be absolute.
+ canon_path path;
+ storage::block_device *bd;
+ storage::dir_entry dir_entry;
+
+ //TODO: instead of passing root, use saved mount points.
+ storage::fs_result follow_symlinks(
+ const vfile &root, std::optional<vfile> &out) const;
+
+ //dir_entry.type is assumed to be directory.
+ storage::fs_result get_child(
+ std::optional<vfile> &out, const utility::string &name) const;
+ //dir_entry.type is assumed to be directory. out must be empty on entry.
+ storage::fs_result get_children(utility::vector<vfile> &out) const;
+
+ //assumes file is a regular file and [start, start + length)
+ //is in bounds of file. start and length are in bytes.
+ storage::fs_result read_file(
+ uint64_t start, uint64_t length, void *into) const;
+
+ };
+
+ //path must be absolute. follows symlinks on all but the last node.
+ //relative_to should be a directory to do the lookup inside; e.g.,
+ //if relative_to is /a/b and path is c, then out becomes /a/b/c.
+ //TODO: instead of passing root, use saved mount points.
+ storage::fs_result lookup_path(
+ const vfile &root, const canon_path &path, std::optional<vfile> &out);
+
+}
+
+#endif