libluna/PathParser: Make dirname() and basename() static functions
All checks were successful
continuous-integration/drone/push Build is passing

This avoids creating a PathParser to use them, which allocates memory that won't be used.
This commit is contained in:
apio 2023-06-19 11:21:58 +02:00
parent f22689fcf5
commit b4a6e4d56d
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 25 additions and 36 deletions

View File

@ -20,8 +20,7 @@ begin:
if (rc.error() == EEXIST) return {}; if (rc.error() == EEXIST) return {};
if (rc.error() == ENOENT) if (rc.error() == ENOENT)
{ {
PathParser parser = TRY(PathParser::create(path.chars())); auto parent = TRY(PathParser::dirname(path));
auto parent = TRY(parser.dirname());
TRY(mkdir_recursively(parent.view(), (0777 & ~s_umask) | S_IWUSR | S_IXUSR)); TRY(mkdir_recursively(parent.view(), (0777 & ~s_umask) | S_IWUSR | S_IXUSR));

View File

@ -71,14 +71,13 @@ namespace VFS
Result<SharedPtr<Inode>> create_directory(const char* path, Credentials auth, SharedPtr<Inode> working_directory) Result<SharedPtr<Inode>> create_directory(const char* path, Credentials auth, SharedPtr<Inode> working_directory)
{ {
auto parser = TRY(PathParser::create(path)); auto parent_path = TRY(PathParser::dirname(path));
auto parent_path = TRY(parser.dirname());
auto parent_inode = TRY(resolve_path(parent_path.chars(), auth, working_directory)); auto parent_inode = TRY(resolve_path(parent_path.chars(), auth, working_directory));
if (!can_write(parent_inode, auth)) return err(EACCES); if (!can_write(parent_inode, auth)) return err(EACCES);
auto child_name = TRY(parser.basename()); auto child_name = TRY(PathParser::basename(path));
TRY(validate_filename(child_name.view())); TRY(validate_filename(child_name.view()));
@ -87,14 +86,13 @@ namespace VFS
Result<SharedPtr<Inode>> create_file(const char* path, Credentials auth, SharedPtr<Inode> working_directory) Result<SharedPtr<Inode>> create_file(const char* path, Credentials auth, SharedPtr<Inode> working_directory)
{ {
auto parser = TRY(PathParser::create(path)); auto parent_path = TRY(PathParser::dirname(path));
auto parent_path = TRY(parser.dirname());
auto parent_inode = TRY(resolve_path(parent_path.chars(), auth, working_directory)); auto parent_inode = TRY(resolve_path(parent_path.chars(), auth, working_directory));
if (!can_write(parent_inode, auth)) return err(EACCES); if (!can_write(parent_inode, auth)) return err(EACCES);
auto child_name = TRY(parser.basename()); auto child_name = TRY(PathParser::basename(path));
TRY(validate_filename(child_name.view())); TRY(validate_filename(child_name.view()));
@ -189,9 +187,8 @@ namespace VFS
Result<void> pivot_root(const char* new_root, const char* put_old, SharedPtr<VFS::Inode> working_directory) Result<void> pivot_root(const char* new_root, const char* put_old, SharedPtr<VFS::Inode> working_directory)
{ {
auto root_parser = TRY(PathParser::create(new_root)); auto new_root_parent = TRY(PathParser::dirname(new_root));
auto new_root_parent = TRY(root_parser.dirname()); auto new_root_path = TRY(PathParser::basename(new_root));
auto new_root_path = TRY(root_parser.basename());
auto new_root_parent_inode = TRY(VFS::resolve_path(new_root_parent.chars(), Credentials {}, working_directory)); auto new_root_parent_inode = TRY(VFS::resolve_path(new_root_parent.chars(), Credentials {}, working_directory));
auto new_root_inode = TRY(new_root_parent_inode->find(new_root_path.chars())); auto new_root_inode = TRY(new_root_parent_inode->find(new_root_path.chars()));
@ -200,9 +197,8 @@ namespace VFS
if (!new_root_inode->is_mountpoint()) return err(EINVAL); if (!new_root_inode->is_mountpoint()) return err(EINVAL);
if (new_root_inode->fs() == g_root_inode->fs()) return err(EBUSY); if (new_root_inode->fs() == g_root_inode->fs()) return err(EBUSY);
auto parser = TRY(PathParser::create(put_old)); auto parent_path = TRY(PathParser::dirname(put_old));
auto parent_path = TRY(parser.dirname()); auto child = TRY(PathParser::basename(put_old));
auto child = TRY(parser.basename());
kdbgln("vfs: Pivoting root from / to %s, using %s as new root", put_old, new_root); kdbgln("vfs: Pivoting root from / to %s, using %s as new root", put_old, new_root);
@ -228,9 +224,8 @@ namespace VFS
Result<void> mount(const char* path, SharedPtr<VFS::FileSystem> fs, Credentials auth, Result<void> mount(const char* path, SharedPtr<VFS::FileSystem> fs, Credentials auth,
SharedPtr<VFS::Inode> working_directory) SharedPtr<VFS::Inode> working_directory)
{ {
auto parser = TRY(PathParser::create(path)); auto parent_path = TRY(PathParser::dirname(path));
auto parent_path = TRY(parser.dirname()); auto child = TRY(PathParser::basename(path));
auto child = TRY(parser.basename());
kinfoln("vfs: Mounting filesystem on target %s", path); kinfoln("vfs: Mounting filesystem on target %s", path);
@ -249,9 +244,8 @@ namespace VFS
Result<void> umount(const char* path, Credentials auth, SharedPtr<VFS::Inode> working_directory) Result<void> umount(const char* path, Credentials auth, SharedPtr<VFS::Inode> working_directory)
{ {
auto parser = TRY(PathParser::create(path)); auto parent_path = TRY(PathParser::dirname(path));
auto parent_path = TRY(parser.dirname()); auto child = TRY(PathParser::basename(path));
auto child = TRY(parser.basename());
if (child.view() == "/") return err(EBUSY); if (child.view() == "/") return err(EBUSY);

View File

@ -13,10 +13,8 @@ Result<u64> sys_unlinkat(Registers*, SyscallArgs args)
Thread* current = Scheduler::current(); Thread* current = Scheduler::current();
PathParser parser = TRY(PathParser::create(path.chars())); auto dirname = TRY(PathParser::dirname(path.view()));
auto basename = TRY(PathParser::basename(path.view()));
auto dirname = TRY(parser.dirname());
auto basename = TRY(parser.basename());
if (basename.view() == ".") return err(EINVAL); if (basename.view() == ".") return err(EINVAL);
@ -47,14 +45,13 @@ Result<u64> sys_symlinkat(Registers*, SyscallArgs args)
auto* current = Scheduler::current(); auto* current = Scheduler::current();
auto parser = TRY(PathParser::create(linkpath.chars())); auto parent = TRY(PathParser::dirname(linkpath.view()));
auto parent = TRY(parser.dirname());
auto parent_inode = TRY(current->resolve_atfile(dirfd, parent, false, true)); auto parent_inode = TRY(current->resolve_atfile(dirfd, parent, false, true));
if (!VFS::can_write(parent_inode, current->auth)) return err(EACCES); if (!VFS::can_write(parent_inode, current->auth)) return err(EACCES);
auto child_name = TRY(parser.basename()); auto child_name = TRY(PathParser::basename(linkpath.view()));
TRY(VFS::validate_filename(child_name.view())); TRY(VFS::validate_filename(child_name.view()));
@ -101,8 +98,7 @@ Result<u64> sys_linkat(Registers*, SyscallArgs args)
auto* current = Scheduler::current(); auto* current = Scheduler::current();
auto parser = TRY(PathParser::create(newpath.chars())); auto parent = TRY(PathParser::dirname(newpath.view()));
auto parent = TRY(parser.dirname());
// FIXME: Use AT_SYMLINK_FOLLOW. // FIXME: Use AT_SYMLINK_FOLLOW.
auto target = TRY(current->resolve_atfile(olddirfd, oldpath, flags & AT_EMPTY_PATH, false)); auto target = TRY(current->resolve_atfile(olddirfd, oldpath, flags & AT_EMPTY_PATH, false));
@ -115,7 +111,7 @@ Result<u64> sys_linkat(Registers*, SyscallArgs args)
if (!VFS::can_write(parent_inode, current->auth)) return err(EACCES); if (!VFS::can_write(parent_inode, current->auth)) return err(EACCES);
auto child_name = TRY(parser.basename()); auto child_name = TRY(PathParser::basename(newpath.view()));
TRY(VFS::validate_filename(child_name.view())); TRY(VFS::validate_filename(child_name.view()));

View File

@ -37,8 +37,8 @@ class PathParser
return m_already_called_next ? (bool)m_strtok_saved_state : is_not_delim(*m_copy); return m_already_called_next ? (bool)m_strtok_saved_state : is_not_delim(*m_copy);
} }
Result<String> basename(); static Result<String> basename(StringView path);
Result<String> dirname(); static Result<String> dirname(StringView path);
Option<const char*> next(); Option<const char*> next();

View File

@ -35,9 +35,9 @@ Option<const char*> PathParser::next()
return result; return result;
} }
Result<String> PathParser::basename() Result<String> PathParser::basename(StringView path)
{ {
char* copy = strdup(m_original); char* copy = strdup(path.chars());
if (!copy) return err(ENOMEM); if (!copy) return err(ENOMEM);
auto guard = make_scope_guard([copy] { free_impl(copy); }); auto guard = make_scope_guard([copy] { free_impl(copy); });
@ -48,9 +48,9 @@ Result<String> PathParser::basename()
return String::from_cstring(result); return String::from_cstring(result);
} }
Result<String> PathParser::dirname() Result<String> PathParser::dirname(StringView path)
{ {
char* copy = strdup(m_original); char* copy = strdup(path.chars());
if (!copy) return err(ENOMEM); if (!copy) return err(ENOMEM);
auto guard = make_scope_guard([copy] { free_impl(copy); }); auto guard = make_scope_guard([copy] { free_impl(copy); });