summaryrefslogtreecommitdiff
path: root/Kernel/Process.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-13 13:13:23 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-13 13:15:05 +0100
commit562663df7c13d27834adacaa1fa5cb9a4ef47c2e (patch)
treed53cf5b0d3b8037183844ffdcc321e25560b0336 /Kernel/Process.cpp
parent7bcd3863382c4151e322a01a8ba573817879bd42 (diff)
downloadserenity-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.cpp54
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)