UserspaceEmulator: Add support for SC_poll syscall

This commit is contained in:
Jean-Baptiste Boric 2021-12-12 11:40:00 +01:00 committed by Andreas Kling
parent 493c958b9e
commit 012d8d7f74
Notes: sideshowbarker 2024-07-17 22:53:10 +09:00
2 changed files with 35 additions and 0 deletions

View file

@ -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);

View file

@ -17,6 +17,7 @@
#include <strings.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
@ -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(&params, params_addr, sizeof(params));
if (params.nfds >= FD_SETSIZE)
return EINVAL;
Vector<pollfd, FD_SETSIZE> 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;
}
}