summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/DoubleBuffer.h4
-rw-r--r--Kernel/FileSystem/InodeFile.cpp9
-rw-r--r--Kernel/Net/IPv4Socket.cpp8
-rw-r--r--Kernel/Net/LocalSocket.cpp16
-rw-r--r--Kernel/Net/LocalSocket.h1
-rw-r--r--Userland/Libraries/LibC/sys/ioctl.h2
-rw-r--r--Userland/Libraries/LibC/sys/ioctl_numbers.h2
7 files changed, 38 insertions, 4 deletions
diff --git a/Kernel/DoubleBuffer.h b/Kernel/DoubleBuffer.h
index 109a4a7bc3..0fd1899dc4 100644
--- a/Kernel/DoubleBuffer.h
+++ b/Kernel/DoubleBuffer.h
@@ -38,6 +38,10 @@ public:
bool is_empty() const { return m_empty; }
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)
{
diff --git a/Kernel/FileSystem/InodeFile.cpp b/Kernel/FileSystem/InodeFile.cpp
index 8cfb21ef26..93ab6e67ce 100644
--- a/Kernel/FileSystem/InodeFile.cpp
+++ b/Kernel/FileSystem/InodeFile.cpp
@@ -64,8 +64,6 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, u64 offset, con
KResult InodeFile::ioctl(FileDescription& description, unsigned request, Userspace<void*> arg)
{
- (void)description;
-
switch (request) {
case FIBMAP: {
if (!Process::current().is_superuser())
@@ -88,6 +86,13 @@ KResult InodeFile::ioctl(FileDescription& description, unsigned request, Userspa
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:
return EINVAL;
}
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp
index 5c56c9dc72..51e61eacd0 100644
--- a/Kernel/Net/IPv4Socket.cpp
+++ b/Kernel/Net/IPv4Socket.cpp
@@ -770,6 +770,14 @@ KResult IPv4Socket::ioctl(FileDescription&, unsigned request, Userspace<void*> a
case SIOCSARP:
case SIOCDARP:
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;
diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp
index 52523fd1bb..06bfe0d19f 100644
--- a/Kernel/Net/LocalSocket.cpp
+++ b/Kernel/Net/LocalSocket.cpp
@@ -16,6 +16,7 @@
#include <Kernel/StdLib.h>
#include <Kernel/UnixTypes.h>
#include <LibC/errno_numbers.h>
+#include <LibC/sys/ioctl_numbers.h>
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)
{
if (m_file)
diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h
index a019e9142b..1c249cfcd9 100644
--- a/Kernel/Net/LocalSocket.h
+++ b/Kernel/Net/LocalSocket.h
@@ -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> 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 ioctl(FileDescription&, unsigned request, Userspace<void*> arg) override;
virtual KResult chown(FileDescription&, uid_t, gid_t) override;
virtual KResult chmod(FileDescription&, mode_t) override;
diff --git a/Userland/Libraries/LibC/sys/ioctl.h b/Userland/Libraries/LibC/sys/ioctl.h
index dbded83718..55d4affa27 100644
--- a/Userland/Libraries/LibC/sys/ioctl.h
+++ b/Userland/Libraries/LibC/sys/ioctl.h
@@ -11,8 +11,6 @@
__BEGIN_DECLS
-#define FIONREAD 0x541B
-
int ioctl(int fd, unsigned request, ...);
__END_DECLS
diff --git a/Userland/Libraries/LibC/sys/ioctl_numbers.h b/Userland/Libraries/LibC/sys/ioctl_numbers.h
index c06726e92d..78a4ba0eae 100644
--- a/Userland/Libraries/LibC/sys/ioctl_numbers.h
+++ b/Userland/Libraries/LibC/sys/ioctl_numbers.h
@@ -83,6 +83,7 @@ enum IOCtlNumber {
SIOCDARP,
FIBMAP,
FIONBIO,
+ FIONREAD,
KCOV_SETBUFSIZE,
KCOV_ENABLE,
KCOV_DISABLE,
@@ -126,3 +127,4 @@ enum IOCtlNumber {
#define SIOCDARP SIOCDARP
#define FIBMAP FIBMAP
#define FIONBIO FIONBIO
+#define FIONREAD FIONREAD