Kernel: Add realpath syscall

This commit is contained in:
Rok Povsic 2019-08-25 18:17:05 +02:00 committed by Andreas Kling
parent 8f50d75184
commit 18fbe4ac83
Notes: sideshowbarker 2024-07-19 12:32:12 +09:00
4 changed files with 34 additions and 0 deletions

View file

@ -1,5 +1,6 @@
#include <AK/ELF/ELFLoader.h> #include <AK/ELF/ELFLoader.h>
#include <AK/ELF/exec_elf.h> #include <AK/ELF/exec_elf.h>
#include <AK/FileSystemPath.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/Time.h> #include <AK/Time.h>
@ -1806,6 +1807,35 @@ int Process::sys$mkdir(const char* pathname, mode_t mode)
return VFS::the().mkdir(StringView(pathname, pathname_length), mode & ~umask(), current_directory()); return VFS::the().mkdir(StringView(pathname, pathname_length), mode & ~umask(), current_directory());
} }
int Process::sys$realpath(const char* pathname, char* buffer, size_t size)
{
if (!validate_read_str(pathname))
return -EFAULT;
size_t pathname_length = strlen(pathname);
if (pathname_length == 0)
return -EINVAL;
if (pathname_length >= size)
return -ENAMETOOLONG;
if (!validate_write(buffer, size))
return -EFAULT;
auto custody_or_error = VFS::the().resolve_path(pathname, current_directory());
if (custody_or_error.is_error())
return custody_or_error.error();
auto& custody = custody_or_error.value();
// FIXME: Once resolve_path is fixed to deal with .. and . , remove the use of FileSystemPath::canonical_path.
FileSystemPath canonical_path(custody->absolute_path());
if (!canonical_path.is_valid()) {
printf("FileSystemPath failed to canonicalize '%s'\n", custody->absolute_path());
return 1;
}
strncpy(buffer, canonical_path.string().characters(), size);
return 0;
};
clock_t Process::sys$times(tms* times) clock_t Process::sys$times(tms* times)
{ {
if (!validate_write_typed(times)) if (!validate_write_typed(times))

View file

@ -222,6 +222,7 @@ public:
int sys$halt(); int sys$halt();
int sys$reboot(); int sys$reboot();
int sys$set_process_icon(int icon_id); int sys$set_process_icon(int icon_id);
int sys$realpath(const char* pathname, char*, size_t);
static void initialize(); static void initialize();

View file

@ -311,6 +311,8 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3
return current->process().sys$mprotect((void*)arg1, (size_t)arg2, (int)arg3); return current->process().sys$mprotect((void*)arg1, (size_t)arg2, (int)arg3);
case Syscall::SC_get_process_name: case Syscall::SC_get_process_name:
return current->process().sys$get_process_name((char*)arg1, (int)arg2); return current->process().sys$get_process_name((char*)arg1, (int)arg2);
case Syscall::SC_realpath:
return current->process().sys$realpath((const char*)arg1, (char*)arg2, (size_t)arg3);
default: default:
kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3); kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
return -ENOSYS; return -ENOSYS;

View file

@ -125,6 +125,7 @@ struct timeval;
__ENUMERATE_SYSCALL(share_buffer_globally) \ __ENUMERATE_SYSCALL(share_buffer_globally) \
__ENUMERATE_SYSCALL(set_process_icon) \ __ENUMERATE_SYSCALL(set_process_icon) \
__ENUMERATE_SYSCALL(mprotect) \ __ENUMERATE_SYSCALL(mprotect) \
__ENUMERATE_SYSCALL(realpath) \
__ENUMERATE_SYSCALL(get_process_name) __ENUMERATE_SYSCALL(get_process_name)
namespace Syscall { namespace Syscall {