diff options
author | brapru <brapru@pm.me> | 2021-08-01 16:36:28 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-10 20:59:53 +0200 |
commit | 342e1f0a84f500c24e80f8a0d1fb3b13f13ac043 (patch) | |
tree | 6466c22265e14074a12a6a1ddbae786a1199b830 /Kernel/Net | |
parent | 0095c7cb7d5a84302572677c229c833928036058 (diff) | |
download | serenity-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.cpp | 3 | ||||
-rw-r--r-- | Kernel/Net/Socket.cpp | 5 |
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) |