39 lines
1.1 KiB
C++
39 lines
1.1 KiB
C++
|
#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);
|
||
|
|
||
|
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()));
|
||
|
|
||
|
current->current_directory = inode;
|
||
|
current->current_directory_path = move(new_path);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
}
|