Ver Fonte

Kernel: Add realpath syscall

Rok Povsic há 6 anos atrás
pai
commit
18fbe4ac83
4 ficheiros alterados com 34 adições e 0 exclusões
  1. 30 0
      Kernel/Process.cpp
  2. 1 0
      Kernel/Process.h
  3. 2 0
      Kernel/Syscall.cpp
  4. 1 0
      Kernel/Syscall.h

+ 30 - 0
Kernel/Process.cpp

@@ -1,5 +1,6 @@
 #include <AK/ELF/ELFLoader.h>
 #include <AK/ELF/exec_elf.h>
+#include <AK/FileSystemPath.h>
 #include <AK/StdLibExtras.h>
 #include <AK/StringBuilder.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());
 }
 
+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)
 {
     if (!validate_write_typed(times))

+ 1 - 0
Kernel/Process.h

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

+ 2 - 0
Kernel/Syscall.cpp

@@ -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);
     case Syscall::SC_get_process_name:
         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:
         kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3);
         return -ENOSYS;

+ 1 - 0
Kernel/Syscall.h

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