diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-13 13:13:23 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-13 13:15:05 +0100 |
commit | 562663df7c13d27834adacaa1fa5cb9a4ef47c2e (patch) | |
tree | d53cf5b0d3b8037183844ffdcc321e25560b0336 /Kernel/Process.cpp | |
parent | 7bcd3863382c4151e322a01a8ba573817879bd42 (diff) | |
download | serenity-562663df7c13d27834adacaa1fa5cb9a4ef47c2e.zip |
Add support for socket send/receive timeouts.
Only the receive timeout is hooked up yet. You can change the timeout by
calling setsockopt(..., SOL_SOCKET, SO_RCVTIMEO, ...).
Use this mechanism to make /bin/ping report timeouts.
Diffstat (limited to 'Kernel/Process.cpp')
-rw-r--r-- | Kernel/Process.cpp | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index f13d17505e..a33327e2b3 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1589,13 +1589,17 @@ int Process::sys$sleep(unsigned seconds) return 0; } +void kgettimeofday(timeval& tv) +{ + tv.tv_sec = RTC::now(); + tv.tv_usec = (PIT::ticks_since_boot() % 1000) * 1000; +} + int Process::sys$gettimeofday(timeval* tv) { if (!validate_write_typed(tv)) return -EFAULT; - auto now = RTC::now(); - tv->tv_sec = now; - tv->tv_usec = (PIT::ticks_since_boot() % 1000) * 1000; + kgettimeofday(*tv); return 0; } @@ -2567,6 +2571,50 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* params) return socket.recvfrom(buffer, buffer_length, flags, addr, addr_length); } +int Process::sys$getsockopt(const Syscall::SC_getsockopt_params* params) +{ + if (!validate_read_typed(params)) + return -EFAULT; + int sockfd = params->sockfd; + int level = params->level; + int option = params->option; + auto* value = params->value; + auto* value_size = (socklen_t*)params->value_size; + + if (!validate_write_typed(value_size)) + return -EFAULT; + if (!validate_write(value, *value_size)) + return -EFAULT; + auto* descriptor = file_descriptor(sockfd); + if (!descriptor) + return -EBADF; + if (!descriptor->is_socket()) + return -ENOTSOCK; + auto& socket = *descriptor->socket(); + return socket.getsockopt(level, option, value, value_size); +} + +int Process::sys$setsockopt(const Syscall::SC_setsockopt_params* params) +{ + if (!validate_read_typed(params)) + return -EFAULT; + int sockfd = params->sockfd; + int level = params->level; + int option = params->option; + auto* value = params->value; + auto value_size = (socklen_t)params->value_size; + + if (!validate_read(value, value_size)) + return -EFAULT; + auto* descriptor = file_descriptor(sockfd); + if (!descriptor) + return -EBADF; + if (!descriptor->is_socket()) + return -ENOTSOCK; + auto& socket = *descriptor->socket(); + return socket.setsockopt(level, option, value, value_size); +} + struct SharedBuffer { SharedBuffer(pid_t pid1, pid_t pid2, int size) : m_pid1(pid1) |