diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.h b/Userland/DevTools/UserspaceEmulator/Emulator.h index b63ec6919d..fda1cd897b 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.h +++ b/Userland/DevTools/UserspaceEmulator/Emulator.h @@ -196,6 +196,7 @@ private: FlatPtr virt$perf_register_string(FlatPtr, size_t); int virt$pipe(FlatPtr pipefd, int flags); u32 virt$pledge(u32); + int virt$poll(FlatPtr); int virt$profiling_disable(pid_t); int virt$profiling_enable(pid_t); int virt$ptsname(int fd, FlatPtr buffer, size_t buffer_size); diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp index 38f183a09d..5d30f6f93a 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -174,6 +175,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) return virt$pipe(arg1, arg2); case SC_pledge: return virt$pledge(arg1); + case SC_poll: + return virt$poll(arg1); case SC_profiling_disable: return virt$profiling_disable(arg1); case SC_profiling_enable: @@ -1620,4 +1623,35 @@ int Emulator::virt$futex(FlatPtr params_addr) // FIXME: Implement this. return 0; } + +int Emulator::virt$poll(FlatPtr params_addr) +{ + Syscall::SC_poll_params params; + mmu().copy_from_vm(¶ms, params_addr, sizeof(params)); + + if (params.nfds >= FD_SETSIZE) + return EINVAL; + + Vector fds; + struct timespec timeout; + u32 sigmask; + + if (params.fds) + mmu().copy_from_vm(fds.data(), (FlatPtr)params.fds, sizeof(pollfd) * params.nfds); + if (params.timeout) + mmu().copy_from_vm(&timeout, (FlatPtr)params.timeout, sizeof(timeout)); + if (params.sigmask) + mmu().copy_from_vm(&sigmask, (FlatPtr)params.sigmask, sizeof(sigmask)); + + int rc = ppoll(params.fds ? fds.data() : nullptr, params.nfds, params.timeout ? &timeout : nullptr, params.sigmask ? &sigmask : nullptr); + if (rc < 0) + return -errno; + + if (params.fds) + mmu().copy_to_vm((FlatPtr)params.fds, fds.data(), sizeof(pollfd) * params.nfds); + if (params.timeout) + mmu().copy_to_vm((FlatPtr)params.timeout, &timeout, sizeof(timeout)); + + return rc; +} }