summaryrefslogtreecommitdiff
path: root/Kernel/Net
diff options
context:
space:
mode:
authorbrapru <brapru@pm.me>2021-08-01 16:36:28 -0400
committerAndreas Kling <kling@serenityos.org>2021-08-10 20:59:53 +0200
commit342e1f0a84f500c24e80f8a0d1fb3b13f13ac043 (patch)
tree6466c22265e14074a12a6a1ddbae786a1199b830 /Kernel/Net
parent0095c7cb7d5a84302572677c229c833928036058 (diff)
downloadserenity-342e1f0a84f500c24e80f8a0d1fb3b13f13ac043.zip
Kernel: Properly implement SO_ERROR option
This fixes the placeholder stub for the SO_ERROR via getsockopt. It leverages the m_so_error value that each socket maintains. The SO_ERROR option obtains and then clears this field, which is useful when checking for errors that occur between socket calls. This uses an integer value to return the SO_ERROR status. Resolves #146
Diffstat (limited to 'Kernel/Net')
-rw-r--r--Kernel/Net/LocalSocket.cpp3
-rw-r--r--Kernel/Net/Socket.cpp5
2 files changed, 3 insertions, 5 deletions
diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp
index 8041c8d459..d6be8a6770 100644
--- a/Kernel/Net/LocalSocket.cpp
+++ b/Kernel/Net/LocalSocket.cpp
@@ -343,9 +343,8 @@ KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKern
}
} else if (!can_read(description, 0)) {
auto unblock_flags = Thread::FileDescriptionBlocker::BlockFlags::None;
- if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted()) {
+ if (Thread::current()->block<Thread::ReadBlocker>({}, description, unblock_flags).was_interrupted())
return set_so_error(EINTR);
- }
}
if (!has_attached_peer(description) && socket_buffer->is_empty())
return 0;
diff --git a/Kernel/Net/Socket.cpp b/Kernel/Net/Socket.cpp
index d7a69fa456..a3c13316ad 100644
--- a/Kernel/Net/Socket.cpp
+++ b/Kernel/Net/Socket.cpp
@@ -181,14 +181,13 @@ KResult Socket::getsockopt(FileDescription&, int level, int option, Userspace<vo
case SO_ERROR: {
if (size < sizeof(int))
return EINVAL;
- dbgln("getsockopt(SO_ERROR): FIXME!");
- int errno = 0;
+ int errno = so_error().error();
if (!copy_to_user(static_ptr_cast<int*>(value), &errno))
return EFAULT;
size = sizeof(int);
if (!copy_to_user(value_size, &size))
return EFAULT;
- return KSuccess;
+ return set_so_error(KSuccess);
}
case SO_BINDTODEVICE:
if (size < IFNAMSIZ)