1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 04:47:34 +00:00

Kernel+LibC: Implement FIONREAD ioctl

FIONREAD gets the number of bytes availible to read from a file
descriptor without blocking. I only implemented it for regular files and
sockets
This commit is contained in:
Peter Elliott 2021-07-26 23:06:22 -06:00 committed by Andreas Kling
parent db92e66902
commit 39a77559f1
7 changed files with 38 additions and 4 deletions

View file

@ -38,6 +38,10 @@ public:
bool is_empty() const { return m_empty; } bool is_empty() const { return m_empty; }
size_t space_for_writing() const { return m_space_for_writing; } size_t space_for_writing() const { return m_space_for_writing; }
size_t immediately_readable() const
{
return (m_read_buffer->size - m_read_buffer_index) + m_write_buffer->size;
}
void set_unblock_callback(Function<void()> callback) void set_unblock_callback(Function<void()> callback)
{ {

View file

@ -64,8 +64,6 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, u64 offset, con
KResult InodeFile::ioctl(FileDescription& description, unsigned request, Userspace<void*> arg) KResult InodeFile::ioctl(FileDescription& description, unsigned request, Userspace<void*> arg)
{ {
(void)description;
switch (request) { switch (request) {
case FIBMAP: { case FIBMAP: {
if (!Process::current().is_superuser()) if (!Process::current().is_superuser())
@ -88,6 +86,13 @@ KResult InodeFile::ioctl(FileDescription& description, unsigned request, Userspa
return KSuccess; return KSuccess;
} }
case FIONREAD: {
int remaining_bytes = inode().size() - description.offset();
if (!copy_to_user(Userspace<int*>(arg), &remaining_bytes))
return EFAULT;
return KSuccess;
}
default: default:
return EINVAL; return EINVAL;
} }

View file

@ -770,6 +770,14 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
case SIOCSARP: case SIOCSARP:
case SIOCDARP: case SIOCDARP:
return ioctl_arp(); return ioctl_arp();
case FIONREAD: {
int readable = m_receive_buffer->immediately_readable();
if (!copy_to_user(Userspace<int*>(arg), &readable))
return EFAULT;
return KSuccess;
}
} }
return EINVAL; return EINVAL;

View file

@ -16,6 +16,7 @@
#include <Kernel/StdLib.h> #include <Kernel/StdLib.h>
#include <Kernel/UnixTypes.h> #include <Kernel/UnixTypes.h>
#include <LibC/errno_numbers.h> #include <LibC/errno_numbers.h>
#include <LibC/sys/ioctl_numbers.h>
namespace Kernel { namespace Kernel {
@ -431,6 +432,21 @@ KResult LocalSocket::getsockopt(FileDescription& description, int level, int opt
} }
} }
KResult LocalSocket::ioctl(FileDescription& description, unsigned request, Userspace<void*> arg)
{
switch (request) {
case FIONREAD: {
int readable = receive_buffer_for(description)->immediately_readable();
if (!copy_to_user(Userspace<int*>(arg), &readable))
return EFAULT;
return KSuccess;
}
}
return ENOTTY;
}
KResult LocalSocket::chmod(FileDescription&, mode_t mode) KResult LocalSocket::chmod(FileDescription&, mode_t mode)
{ {
if (m_file) if (m_file)

View file

@ -47,6 +47,7 @@ public:
virtual KResultOr<size_t> sendto(FileDescription&, const UserOrKernelBuffer&, size_t, int, Userspace<const sockaddr*>, socklen_t) override; virtual KResultOr<size_t> sendto(FileDescription&, const UserOrKernelBuffer&, size_t, int, Userspace<const sockaddr*>, socklen_t) override;
virtual KResultOr<size_t> recvfrom(FileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) override; virtual KResultOr<size_t> recvfrom(FileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Time&) override;
virtual KResult getsockopt(FileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override; virtual KResult getsockopt(FileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override;
virtual KResult ioctl(FileDescription&, unsigned request, Userspace<void*> arg) override;
virtual KResult chown(FileDescription&, uid_t, gid_t) override; virtual KResult chown(FileDescription&, uid_t, gid_t) override;
virtual KResult chmod(FileDescription&, mode_t) override; virtual KResult chmod(FileDescription&, mode_t) override;

View file

@ -11,8 +11,6 @@
__BEGIN_DECLS __BEGIN_DECLS
#define FIONREAD 0x541B
int ioctl(int fd, unsigned request, ...); int ioctl(int fd, unsigned request, ...);
__END_DECLS __END_DECLS

View file

@ -83,6 +83,7 @@ enum IOCtlNumber {
SIOCDARP, SIOCDARP,
FIBMAP, FIBMAP,
FIONBIO, FIONBIO,
FIONREAD,
KCOV_SETBUFSIZE, KCOV_SETBUFSIZE,
KCOV_ENABLE, KCOV_ENABLE,
KCOV_DISABLE, KCOV_DISABLE,
@ -126,3 +127,4 @@ enum IOCtlNumber {
#define SIOCDARP SIOCDARP #define SIOCDARP SIOCDARP
#define FIBMAP FIBMAP #define FIBMAP FIBMAP
#define FIONBIO FIONBIO #define FIONBIO FIONBIO
#define FIONREAD FIONREAD