summaryrefslogtreecommitdiff
path: root/DevTools
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-07-27 16:28:25 +0200
committerAndreas Kling <kling@serenityos.org>2020-07-27 16:28:40 +0200
commit368cea4094709a1e493b419c5bcc86040a207a38 (patch)
treefa9b9c72461bd80c4a3e3fae9cdcc28bba90f470 /DevTools
parentf097ed6ada0b9aa8f1ff7896eccbdecec78980aa (diff)
downloadserenity-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.cpp36
-rw-r--r--DevTools/UserspaceEmulator/Emulator.h2
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(&params, 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);