From 5b587d199ed6a08a79102f6efc9fd21ae54eb0e5 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 8 Aug 2025 01:14:11 +0300 Subject: [PATCH] Kernel/LibC: Implement FIONREAD for tcp and udp sockets --- kernel/include/kernel/Networking/TCPSocket.h | 3 +++ kernel/include/kernel/Networking/UDPSocket.h | 4 +++- kernel/kernel/Networking/TCPSocket.cpp | 13 +++++++++++++ kernel/kernel/Networking/UDPSocket.cpp | 19 +++++++++++++++++++ userspace/libraries/LibC/include/sys/ioctl.h | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/kernel/include/kernel/Networking/TCPSocket.h b/kernel/include/kernel/Networking/TCPSocket.h index 746dcf03..0a0b63d7 100644 --- a/kernel/include/kernel/Networking/TCPSocket.h +++ b/kernel/include/kernel/Networking/TCPSocket.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -63,6 +64,8 @@ namespace Kernel virtual BAN::ErrorOr recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override; virtual BAN::ErrorOr getpeername_impl(sockaddr*, socklen_t*) override; + virtual BAN::ErrorOr ioctl_impl(int, void*) override; + virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override; virtual bool can_read_impl() const override; diff --git a/kernel/include/kernel/Networking/UDPSocket.h b/kernel/include/kernel/Networking/UDPSocket.h index 4ded8d98..6e39381e 100644 --- a/kernel/include/kernel/Networking/UDPSocket.h +++ b/kernel/include/kernel/Networking/UDPSocket.h @@ -38,6 +38,8 @@ namespace Kernel virtual BAN::ErrorOr recvfrom_impl(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len) override; virtual BAN::ErrorOr getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); } + virtual BAN::ErrorOr ioctl_impl(int, void*) override; + virtual bool can_read_impl() const override { return !m_packets.empty(); } virtual bool can_write_impl() const override { return true; } virtual bool has_error_impl() const override { return false; } @@ -59,7 +61,7 @@ namespace Kernel BAN::CircularQueue m_packets; size_t m_packet_total_size { 0 }; SpinLock m_packet_lock; - ThreadBlocker m_packet_thread_blocker; + ThreadBlocker m_packet_thread_blocker; friend class BAN::RefPtr; }; diff --git a/kernel/kernel/Networking/TCPSocket.cpp b/kernel/kernel/Networking/TCPSocket.cpp index a04535b2..b91b2d55 100644 --- a/kernel/kernel/Networking/TCPSocket.cpp +++ b/kernel/kernel/Networking/TCPSocket.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace Kernel { @@ -255,6 +256,18 @@ namespace Kernel return {}; } + BAN::ErrorOr TCPSocket::ioctl_impl(int request, void* argument) + { + switch (request) + { + case FIONREAD: + *static_cast(argument) = m_recv_window.data_size; + return 0; + } + + return NetworkSocket::ioctl_impl(request, argument); + } + bool TCPSocket::can_read_impl() const { if (m_has_connected && !m_has_sent_zero && m_state != State::Established && m_state != State::Listen) diff --git a/kernel/kernel/Networking/UDPSocket.cpp b/kernel/kernel/Networking/UDPSocket.cpp index ce0b9fba..763ab4ec 100644 --- a/kernel/kernel/Networking/UDPSocket.cpp +++ b/kernel/kernel/Networking/UDPSocket.cpp @@ -4,6 +4,7 @@ #include #include +#include namespace Kernel { @@ -138,4 +139,22 @@ namespace Kernel return TRY(m_network_layer.sendto(*this, message, address, address_len)); } + BAN::ErrorOr UDPSocket::ioctl_impl(int request, void* argument) + { + switch (request) + { + case FIONREAD: + { + SpinLockGuard guard(m_packet_lock); + if (m_packets.empty()) + *static_cast(argument) = 0; + else + *static_cast(argument) = m_packets.front().packet_size; + return 0; + } + } + + return NetworkSocket::ioctl_impl(request, argument); + } + } diff --git a/userspace/libraries/LibC/include/sys/ioctl.h b/userspace/libraries/LibC/include/sys/ioctl.h index 33a0a781..fe7627c7 100644 --- a/userspace/libraries/LibC/include/sys/ioctl.h +++ b/userspace/libraries/LibC/include/sys/ioctl.h @@ -37,6 +37,8 @@ __BEGIN_DECLS #define KDLOADFONT 30 +#define FIONREAD 40 /* get number of input bytes available */ + struct winsize { unsigned short ws_row;