vfs: Add support for creating directories given a full path

This commit is contained in:
apio 2023-03-11 01:13:44 +01:00
parent 6fd28379a9
commit d95ef110c9
Signed by: apio
GPG Key ID: B8A7D06E42258954
11 changed files with 114 additions and 9 deletions

View File

@ -17,14 +17,9 @@ namespace VFS
kdbgln("vfs: trying to resolve path %s", path);
SharedPtr<Inode> current_inode;
SharedPtr<Inode> current_inode = root_fs->root_inode();
if (parser.is_absolute()) { current_inode = root_fs->root_inode(); }
else
{
kwarnln("vfs: cannot resolve path '%s', as relative paths are not supported yet", path);
return err(ENOTSUP);
}
// FIXME: Properly handle relative paths.
const char* section;
while (parser.next().try_set_value(section))
@ -35,4 +30,18 @@ namespace VFS
return current_inode;
}
Result<SharedPtr<Inode>> create_directory(const char* path)
{
auto parser = TRY(PathParser::create(path));
auto parent_path = TRY(parser.dirname());
auto parent_inode = TRY(resolve_path(parent_path.chars()));
auto child_name = TRY(parser.basename());
kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars());
return parent_inode->create_subdirectory(child_name.chars());
}
}

View File

@ -78,5 +78,7 @@ namespace VFS
Result<SharedPtr<Inode>> resolve_path(const char* path);
Result<SharedPtr<Inode>> create_directory(const char* path);
Inode& root_inode();
}

View File

@ -58,7 +58,7 @@ static Result<void> try_init_vfs()
kinfoln("root inode's '.' entry inode number: %zu", TRY(root_inode.find("."))->inode_number());
kinfoln("root inode's '..' entry inode number: %zu", TRY(root_inode.find(".."))->inode_number());
TRY(root_inode.create_subdirectory("etc"));
TRY(VFS::create_directory("/etc/"));
kinfoln("root inode's 'etc' entry inode number: %zu", TRY(root_inode.find("etc"))->inode_number());

View File

@ -7,6 +7,7 @@ set(FREESTANDING_SOURCES
src/Format.cpp
src/NumberParsing.cpp
src/CString.cpp
src/CPath.cpp
src/Units.cpp
src/SystemError.cpp
src/Bitmap.cpp

View File

@ -0,0 +1,4 @@
#pragma once
char* basename(char*);
char* dirname(char*);

View File

@ -33,4 +33,5 @@ extern "C"
[[deprecated]] char* strcat(char* dst, const char* src);
char* strchr(const char* str, int c);
char* strrchr(const char* str, int c);
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <luna/CString.h>
#include <luna/Heap.h>
#include <luna/OwnedStringView.h>
class PathParser
{
@ -17,6 +18,9 @@ class PathParser
return *m_original == '/';
}
Result<OwnedStringView> basename();
Result<OwnedStringView> dirname();
Option<const char*> next();
private:

47
libluna/src/CPath.cpp Normal file
View File

@ -0,0 +1,47 @@
#include <luna/CPath.h>
#include <luna/CString.h>
static char dot[] = ".";
char* basename(char* path)
{
// If path is NULL, or the string's length is 0, return .
if (!path) return dot;
size_t len = strlen(path);
if (!len) return dot;
// Strip trailing slashes.
char* it = path + len - 1;
while (*it == '/' && it != path) { it--; }
*(it + 1) = 0;
if (it == path) return path;
// Return path from the first character if there are no more slashes, or from the first character after the last
// slash.
char* beg = strrchr(path, '/');
if (!beg) return path;
return beg + 1;
}
char* dirname(char* path)
{
// If path is NULL, or the string's length is 0, return .
if (!path) return dot;
size_t len = strlen(path);
if (!len) return dot;
// Strip trailing slashes.
char* it = path + len - 1;
while (*it == '/' && it != path) { it--; }
*(char*)(it + 1) = 0;
if (it == path) return path;
// Search for the last slash. If there is none, return .
// Otherwise, we end the string there and return.
char* end = strrchr(path, '/');
if (!end) return dot;
if (end != path) *end = 0;
else
*(end + 1) = 0;
return path;
}

View File

@ -126,6 +126,15 @@ extern "C"
return NULL;
}
char* strrchr(const char* str, int c)
{
const char* s = str + strlen(str);
while (s != str && *s != (char)c) s--;
if (s != str) return const_cast<char*>(s);
if (*s == (char)c) return const_cast<char*>(s);
return NULL;
}
usize strlcpy(char* dest, const char* src, usize len)
{
usize src_len = strlen(src);

View File

@ -1,4 +1,6 @@
#include <luna/CPath.h>
#include <luna/PathParser.h>
#include <luna/ScopeGuard.h>
Result<PathParser> PathParser::create(const char* path)
{
@ -31,3 +33,29 @@ Option<const char*> PathParser::next()
return result;
}
Result<OwnedStringView> PathParser::basename()
{
char* copy = strdup(m_original);
if (!copy) return err(ENOMEM);
auto guard = make_scope_guard([copy] { free_impl(copy); });
char* result = ::basename(copy);
// We must copy this as we cannot rely on the original string.
return OwnedStringView::from_string_literal(result);
}
Result<OwnedStringView> PathParser::dirname()
{
char* copy = strdup(m_original);
if (!copy) return err(ENOMEM);
auto guard = make_scope_guard([copy] { free_impl(copy); });
char* result = ::dirname(copy);
// We must copy this as we cannot rely on the original string.
return OwnedStringView::from_string_literal(result);
}

View File

@ -46,7 +46,7 @@ Result<TarStream::Entry> TarStream::parse_header(const TarStream::TarHeader* hdr
entry.mode = (mode_t)parse_unsigned_integer(hdr->mode, nullptr, 8);
entry.m_pos = m_offset;
entry.m_data = (u8*)(m_base + m_offset);
entry.m_data = (u8*)m_base + m_offset;
switch (hdr->typeflag)
{