Bladeren bron

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
brapru 4 jaren geleden
bovenliggende
commit
342e1f0a84
2 gewijzigde bestanden met toevoegingen van 3 en 5 verwijderingen
  1. 1 2
      Kernel/Net/LocalSocket.cpp
  2. 2 3
      Kernel/Net/Socket.cpp

+ 1 - 2
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;

+ 2 - 3
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)