mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-02-09 09:17:13 +00:00
To be able to do this, we add a new class called CustodyBase, which can be resolved on-demand internally in the VirtualFileSystem resolving path code. When being resolved, CustodyBase will return a known custody if it was constructed with such, if that's not the case it will provide the root custody if the original path is absolute. Lastly, if that's not the case as well, it will resolve the given dirfd to provide a Custody object.
60 lines
1.9 KiB
C++
60 lines
1.9 KiB
C++
/*
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <AK/RefPtr.h>
|
|
#include <Kernel/FileSystem/Custody.h>
|
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
|
#include <Kernel/Tasks/Process.h>
|
|
|
|
namespace Kernel {
|
|
|
|
ErrorOr<FlatPtr> Process::sys$chdir(Userspace<char const*> user_path, size_t path_length)
|
|
{
|
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
|
TRY(require_promise(Pledge::rpath));
|
|
auto path = TRY(get_syscall_path_argument(user_path, path_length));
|
|
|
|
RefPtr<Custody> new_directory = TRY(VirtualFileSystem::the().open_directory(credentials(), path->view(), current_directory()));
|
|
m_current_directory.with([&](auto& current_directory) {
|
|
// NOTE: We use swap() here to avoid manipulating the ref counts while holding the lock.
|
|
swap(current_directory, new_directory);
|
|
});
|
|
return 0;
|
|
}
|
|
|
|
ErrorOr<FlatPtr> Process::sys$fchdir(int fd)
|
|
{
|
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
|
TRY(require_promise(Pledge::stdio));
|
|
auto description = TRY(open_file_description(fd));
|
|
if (!description->is_directory())
|
|
return ENOTDIR;
|
|
if (!description->metadata().may_execute(credentials()))
|
|
return EACCES;
|
|
m_current_directory.with([&](auto& current_directory) {
|
|
current_directory = description->custody();
|
|
});
|
|
return 0;
|
|
}
|
|
|
|
ErrorOr<FlatPtr> Process::sys$getcwd(Userspace<char*> buffer, size_t size)
|
|
{
|
|
VERIFY_NO_PROCESS_BIG_LOCK(this);
|
|
TRY(require_promise(Pledge::rpath));
|
|
|
|
if (size > NumericLimits<ssize_t>::max())
|
|
return EINVAL;
|
|
|
|
auto path = TRY(current_directory()->try_serialize_absolute_path());
|
|
size_t ideal_size = path->length() + 1;
|
|
auto size_to_copy = min(ideal_size, size);
|
|
TRY(copy_to_user(buffer, path->characters(), size_to_copy));
|
|
// Note: we return the whole size here, not the copied size.
|
|
return ideal_size;
|
|
}
|
|
|
|
}
|