#ifndef MERCURY_KERNEL_VFILE_HPP #define MERCURY_KERNEL_VFILE_HPP #include #include //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 mercury::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 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 &out) const; //dir_entry.type is assumed to be directory. storage::fs_result get_child( std::optional &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 &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 &out); } #endif