From 2ab3eb41096ccb17317ea8a4f43fbebb44acdfcf Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 12 Feb 2024 23:46:27 +0200 Subject: [PATCH] Kernel: Fix bugs in select Unix domain socket is now select readable when it has pending connection --- kernel/kernel/Networking/UNIX/Socket.cpp | 2 ++ kernel/kernel/Process.cpp | 29 ++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/kernel/kernel/Networking/UNIX/Socket.cpp b/kernel/kernel/Networking/UNIX/Socket.cpp index a78d6f79..3f8eb1f4 100644 --- a/kernel/kernel/Networking/UNIX/Socket.cpp +++ b/kernel/kernel/Networking/UNIX/Socket.cpp @@ -253,6 +253,8 @@ namespace Kernel if (m_info.has()) { auto& connection_info = m_info.get(); + if (!connection_info.pending_connections.empty()) + return true; if (!connection_info.connection) return false; } diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 83eeb862..e0f2e6c5 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1048,8 +1048,8 @@ namespace Kernel fd_set writefds; FD_ZERO(&writefds); fd_set errorfds; FD_ZERO(&errorfds); - long set_bits = 0; - while (set_bits == 0) + int set_bits = 0; + for (;;) { if (arguments->timeout && SystemTimer::get().ms_since_boot() >= timedout_ms) break; @@ -1072,7 +1072,7 @@ namespace Kernel if (!mode.ifreg() && !mode.ififo() && !mode.ifsock() && !inode->is_pipe() && !inode->is_tty()) return; - if ((inode_or_error.value().ptr()->*func)()) + if ((inode.ptr()->*func)()) { FD_SET(fd, dest); set_bits++; @@ -1083,18 +1083,33 @@ namespace Kernel { update_fds(i, arguments->readfds, &readfds, &Inode::can_read); update_fds(i, arguments->writefds, &writefds, &Inode::can_write); - update_fds(i, arguments->errorfds, &errorfds, &Inode::can_read); + update_fds(i, arguments->errorfds, &errorfds, &Inode::has_error); } + if (set_bits > 0) + break; + + LockFreeGuard free(m_lock); SystemTimer::get().sleep(1); } if (arguments->readfds) - memcpy(arguments->readfds, &readfds, sizeof(fd_set)); + FD_ZERO(arguments->readfds); if (arguments->writefds) - memcpy(arguments->writefds, &writefds, sizeof(fd_set)); + FD_ZERO(arguments->writefds); if (arguments->errorfds) - memcpy(arguments->errorfds, &errorfds, sizeof(fd_set)); + FD_ZERO(arguments->errorfds); + + for (int i = 0; i < arguments->nfds; i++) + { + if (arguments->readfds && FD_ISSET(i, &readfds)) + FD_SET(i, arguments->readfds); + if (arguments->writefds && FD_ISSET(i, &writefds)) + FD_SET(i, arguments->writefds); + if (arguments->errorfds && FD_ISSET(i, &errorfds)) + FD_SET(i, arguments->errorfds); + } + return set_bits; }