2023-04-11 20:15:21 +00:00
|
|
|
#include "memory/MemoryManager.h"
|
|
|
|
#include "sys/Syscall.h"
|
|
|
|
#include "thread/Scheduler.h"
|
|
|
|
#include <luna/PathParser.h>
|
|
|
|
|
|
|
|
Result<u64> sys_chdir(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
|
|
|
|
|
|
|
|
Thread* current = Scheduler::current();
|
|
|
|
|
|
|
|
if (PathParser::is_absolute(path.view()))
|
|
|
|
{
|
|
|
|
SharedPtr<VFS::Inode> inode = TRY(VFS::resolve_path(path.chars(), current->auth));
|
|
|
|
|
|
|
|
if (inode->type() != VFS::InodeType::Directory) return err(ENOTDIR);
|
|
|
|
|
2023-05-17 18:37:01 +00:00
|
|
|
inode->add_handle();
|
|
|
|
if (current->current_directory) current->current_directory->remove_handle();
|
|
|
|
|
2023-04-11 20:15:21 +00:00
|
|
|
current->current_directory = inode;
|
|
|
|
current->current_directory_path = move(path);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SharedPtr<VFS::Inode> inode = TRY(VFS::resolve_path(path.chars(), current->auth, current->current_directory));
|
|
|
|
|
|
|
|
if (inode->type() != VFS::InodeType::Directory) return err(ENOTDIR);
|
|
|
|
|
|
|
|
auto old_wdir = current->current_directory_path.view();
|
|
|
|
|
|
|
|
String new_path = TRY(PathParser::join(old_wdir.is_empty() ? "/"_sv : old_wdir, path.view()));
|
|
|
|
|
2023-05-17 18:37:01 +00:00
|
|
|
inode->add_handle();
|
|
|
|
if (current->current_directory) current->current_directory->remove_handle();
|
|
|
|
|
2023-04-11 20:15:21 +00:00
|
|
|
current->current_directory = inode;
|
|
|
|
current->current_directory_path = move(new_path);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2023-04-11 20:45:13 +00:00
|
|
|
|
|
|
|
Result<u64> sys_getcwd(Registers*, SyscallArgs args)
|
|
|
|
{
|
|
|
|
u8* buf = (u8*)args[0];
|
|
|
|
usize size = (usize)args[1];
|
|
|
|
|
|
|
|
Thread* current = Scheduler::current();
|
|
|
|
|
|
|
|
StringView cwd = current->current_directory_path.view();
|
|
|
|
if (cwd.is_empty()) cwd = "/"_sv;
|
|
|
|
|
|
|
|
usize cwd_size = cwd.length() + 1;
|
|
|
|
|
|
|
|
if (cwd_size > size) return cwd_size;
|
|
|
|
|
|
|
|
if (!MemoryManager::copy_to_user(buf, cwd.chars(), cwd_size)) return err(EFAULT);
|
|
|
|
|
|
|
|
return cwd_size;
|
|
|
|
}
|