Bläddra i källkod

UserspaceEmulator: Add syscalls: stat(), realpath(), gethostname()

This is enough to run /bin/ls :^)
Andreas Kling 5 år sedan
förälder
incheckning
b8d3dbcf2d
2 ändrade filer med 57 tillägg och 0 borttagningar
  1. 54 0
      DevTools/UserspaceEmulator/Emulator.cpp
  2. 3 0
      DevTools/UserspaceEmulator/Emulator.h

+ 54 - 0
DevTools/UserspaceEmulator/Emulator.cpp

@@ -245,6 +245,12 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
     switch (function) {
     case SC_execve:
         return virt$execve(arg1);
+    case SC_stat:
+        return virt$stat(arg1);
+    case SC_realpath:
+        return virt$realpath(arg1);
+    case SC_gethostname:
+        return virt$gethostname(arg1, arg2);
     case SC_ioctl:
         return virt$ioctl(arg1, arg2, arg3);
     case SC_get_dir_entries:
@@ -927,4 +933,52 @@ int Emulator::virt$execve(FlatPtr params_addr)
     return execve(argv[0], (char* const*)argv.data(), (char* const*)envp.data());
 }
 
+int Emulator::virt$stat(FlatPtr params_addr)
+{
+    Syscall::SC_stat_params params;
+    mmu().copy_from_vm(&params, params_addr, sizeof(params));
+
+    auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
+    struct stat host_statbuf;
+    int rc;
+    if (params.follow_symlinks)
+        rc = stat(path.characters(), &host_statbuf);
+    else
+        rc = lstat(path.characters(), &host_statbuf);
+    if (rc < 0)
+        return -errno;
+    mmu().copy_to_vm((FlatPtr)params.statbuf, &host_statbuf, sizeof(host_statbuf));
+    return rc;
+}
+
+int Emulator::virt$realpath(FlatPtr params_addr)
+{
+    Syscall::SC_realpath_params params;
+    mmu().copy_from_vm(&params, params_addr, sizeof(params));
+
+    auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
+    char host_buffer[PATH_MAX] = {};
+
+    Syscall::SC_realpath_params host_params;
+    host_params.path = { path.characters(), path.length() };
+    host_params.buffer = { host_buffer, sizeof(host_buffer) };
+    int rc = syscall(SC_realpath, &host_params);
+    if (rc < 0)
+        return rc;
+    mmu().copy_to_vm((FlatPtr)params.buffer.data, host_buffer, min(params.buffer.size, sizeof(host_buffer)));
+    return rc;
+}
+
+int Emulator::virt$gethostname(FlatPtr buffer, ssize_t buffer_size)
+{
+    if (buffer_size < 0)
+        return -EINVAL;
+    auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
+    int rc = syscall(SC_gethostname, host_buffer.data(), host_buffer.size());
+    if (rc < 0)
+        return rc;
+    mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
+    return rc;
+}
+
 }

+ 3 - 0
DevTools/UserspaceEmulator/Emulator.h

@@ -74,6 +74,9 @@ private:
     int virt$execve(FlatPtr);
     int virt$get_dir_entries(int fd, FlatPtr buffer, ssize_t);
     int virt$ioctl(int fd, unsigned, FlatPtr);
+    int virt$stat(FlatPtr);
+    int virt$realpath(FlatPtr);
+    int virt$gethostname(FlatPtr, ssize_t);
     int virt$usleep(useconds_t);
     int virt$shbuf_create(int size, FlatPtr buffer);
     int virt$shbuf_allow_pid(int, pid_t peer_pid);