vfs: Add support for creating directories given a full path
This commit is contained in:
parent
6fd28379a9
commit
d95ef110c9
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
4
libluna/include/luna/CPath.h
Normal file
4
libluna/include/luna/CPath.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
char* basename(char*);
|
||||
char* dirname(char*);
|
@ -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);
|
||||
}
|
||||
|
@ -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
47
libluna/src/CPath.cpp
Normal 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;
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user