diff options
author | Andreas Kling <kling@serenityos.org> | 2020-07-27 16:28:25 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-27 16:28:40 +0200 |
commit | 368cea4094709a1e493b419c5bcc86040a207a38 (patch) | |
tree | fa9b9c72461bd80c4a3e3fae9cdcc28bba90f470 /DevTools | |
parent | f097ed6ada0b9aa8f1ff7896eccbdecec78980aa (diff) | |
download | serenity-368cea4094709a1e493b419c5bcc86040a207a38.zip |
UserspaceEmulator: Implement the accept() and setsockopt() syscalls
It's now possible to run LookupServer in UE (by setting up SystemServer
to run the service inside UE.) No bugs found, but very cool! :^)
Diffstat (limited to 'DevTools')
-rw-r--r-- | DevTools/UserspaceEmulator/Emulator.cpp | 36 | ||||
-rw-r--r-- | DevTools/UserspaceEmulator/Emulator.h | 2 |
2 files changed, 37 insertions, 1 deletions
diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index 80880c4476..a8bc5e61c9 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -316,6 +316,10 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) return virt$dbgputch(arg1); case SC_fchmod: return virt$fchmod(arg1, arg2); + case SC_accept: + return virt$accept(arg1, arg2, arg3); + case SC_setsockopt: + return virt$setsockopt(arg1); case SC_bind: return virt$bind(arg1, arg2, arg3); case SC_connect: @@ -343,7 +347,7 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) return virt$getrandom(arg1, arg2, arg3); default: - warn() << "Unimplemented syscall: " << Syscall::to_string((Syscall::Function)function); + dbg() << "Unimplemented syscall: " << Syscall::to_string((Syscall::Function)function); dump_backtrace(); TODO(); } @@ -456,6 +460,36 @@ int Emulator::virt$fchmod(int fd, mode_t mode) return syscall(SC_fchmod, fd, mode); } +int Emulator::virt$setsockopt(FlatPtr params_addr) +{ + Syscall::SC_setsockopt_params params; + mmu().copy_from_vm(¶ms, params_addr, sizeof(params)); + + if (params.option == SO_RCVTIMEO) { + auto host_value_buffer = ByteBuffer::create_zeroed(params.value_size); + mmu().copy_from_vm(host_value_buffer.data(), (FlatPtr)params.value, params.value_size); + int rc = setsockopt(params.sockfd, params.level, SO_RCVTIMEO, host_value_buffer.data(), host_value_buffer.size()); + if (rc < 0) + return -errno; + return rc; + } + + TODO(); +} + +int Emulator::virt$accept(int sockfd, FlatPtr address, FlatPtr address_length) +{ + socklen_t host_address_length = 0; + mmu().copy_from_vm(&host_address_length, address_length, sizeof(host_address_length)); + auto host_buffer = ByteBuffer::create_zeroed(host_address_length); + int rc = syscall(SC_accept, sockfd, host_buffer.data(), &host_address_length); + if (rc < 0) + return rc; + mmu().copy_to_vm(address, host_buffer.data(), min((socklen_t)host_buffer.size(), host_address_length)); + mmu().copy_to_vm(address_length, &host_address_length, sizeof(host_address_length)); + return rc; +} + int Emulator::virt$bind(int sockfd, FlatPtr address, socklen_t address_length) { auto buffer = mmu().copy_buffer_from_vm(address, address_length); diff --git a/DevTools/UserspaceEmulator/Emulator.h b/DevTools/UserspaceEmulator/Emulator.h index 5f23ec608d..f08fd53efa 100644 --- a/DevTools/UserspaceEmulator/Emulator.h +++ b/DevTools/UserspaceEmulator/Emulator.h @@ -113,7 +113,9 @@ private: int virt$lseek(int fd, off_t offset, int whence); int virt$socket(int, int, int); int virt$getsockopt(FlatPtr); + int virt$setsockopt(FlatPtr); int virt$select(FlatPtr); + int virt$accept(int sockfd, FlatPtr address, FlatPtr address_length); int virt$bind(int sockfd, FlatPtr address, socklen_t address_length); int virt$recvfrom(FlatPtr); int virt$connect(int sockfd, FlatPtr address, socklen_t address_size); |