mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:17:35 +00:00
Kernel: Don't assert when reading from a listening-mode local socket
Instead just fail with EINVAL as a listening socket is never suitable for reading from. Fixes #4511.
This commit is contained in:
parent
80ae407d73
commit
c6a0694f50
2 changed files with 21 additions and 16 deletions
|
@ -286,37 +286,42 @@ KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const UserOr
|
||||||
{
|
{
|
||||||
if (!has_attached_peer(description))
|
if (!has_attached_peer(description))
|
||||||
return KResult(-EPIPE);
|
return KResult(-EPIPE);
|
||||||
ssize_t nwritten = send_buffer_for(description).write(data, data_size);
|
auto* socket_buffer = send_buffer_for(description);
|
||||||
|
if (!socket_buffer)
|
||||||
|
return KResult(-EINVAL);
|
||||||
|
ssize_t nwritten = socket_buffer->write(data, data_size);
|
||||||
if (nwritten > 0)
|
if (nwritten > 0)
|
||||||
Thread::current()->did_unix_socket_write(nwritten);
|
Thread::current()->did_unix_socket_write(nwritten);
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoubleBuffer& LocalSocket::receive_buffer_for(FileDescription& description)
|
DoubleBuffer* LocalSocket::receive_buffer_for(FileDescription& description)
|
||||||
{
|
{
|
||||||
auto role = this->role(description);
|
auto role = this->role(description);
|
||||||
if (role == Role::Accepted)
|
if (role == Role::Accepted)
|
||||||
return m_for_server;
|
return &m_for_server;
|
||||||
if (role == Role::Connected)
|
if (role == Role::Connected)
|
||||||
return m_for_client;
|
return &m_for_client;
|
||||||
ASSERT_NOT_REACHED();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoubleBuffer& LocalSocket::send_buffer_for(FileDescription& description)
|
DoubleBuffer* LocalSocket::send_buffer_for(FileDescription& description)
|
||||||
{
|
{
|
||||||
auto role = this->role(description);
|
auto role = this->role(description);
|
||||||
if (role == Role::Connected)
|
if (role == Role::Connected)
|
||||||
return m_for_server;
|
return &m_for_server;
|
||||||
if (role == Role::Accepted)
|
if (role == Role::Accepted)
|
||||||
return m_for_client;
|
return &m_for_client;
|
||||||
ASSERT_NOT_REACHED();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, timeval&)
|
KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, timeval&)
|
||||||
{
|
{
|
||||||
auto& buffer_for_me = receive_buffer_for(description);
|
auto* socket_buffer = receive_buffer_for(description);
|
||||||
|
if (!socket_buffer)
|
||||||
|
return KResult(-EINVAL);
|
||||||
if (!description.is_blocking()) {
|
if (!description.is_blocking()) {
|
||||||
if (buffer_for_me.is_empty()) {
|
if (socket_buffer->is_empty()) {
|
||||||
if (!has_attached_peer(description))
|
if (!has_attached_peer(description))
|
||||||
return 0;
|
return 0;
|
||||||
return KResult(-EAGAIN);
|
return KResult(-EAGAIN);
|
||||||
|
@ -326,10 +331,10 @@ KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, UserOrKern
|
||||||
if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description, unblock_flags).was_interrupted())
|
if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description, unblock_flags).was_interrupted())
|
||||||
return KResult(-EINTR);
|
return KResult(-EINTR);
|
||||||
}
|
}
|
||||||
if (!has_attached_peer(description) && buffer_for_me.is_empty())
|
if (!has_attached_peer(description) && socket_buffer->is_empty())
|
||||||
return 0;
|
return 0;
|
||||||
ASSERT(!buffer_for_me.is_empty());
|
ASSERT(!socket_buffer->is_empty());
|
||||||
int nread = buffer_for_me.read(buffer, buffer_size);
|
auto nread = socket_buffer->read(buffer, buffer_size);
|
||||||
if (nread > 0)
|
if (nread > 0)
|
||||||
Thread::current()->did_unix_socket_read(nread);
|
Thread::current()->did_unix_socket_read(nread);
|
||||||
return nread;
|
return nread;
|
||||||
|
|
|
@ -72,8 +72,8 @@ private:
|
||||||
virtual bool is_local() const override { return true; }
|
virtual bool is_local() const override { return true; }
|
||||||
bool has_attached_peer(const FileDescription&) const;
|
bool has_attached_peer(const FileDescription&) const;
|
||||||
static Lockable<InlineLinkedList<LocalSocket>>& all_sockets();
|
static Lockable<InlineLinkedList<LocalSocket>>& all_sockets();
|
||||||
DoubleBuffer& receive_buffer_for(FileDescription&);
|
DoubleBuffer* receive_buffer_for(FileDescription&);
|
||||||
DoubleBuffer& send_buffer_for(FileDescription&);
|
DoubleBuffer* send_buffer_for(FileDescription&);
|
||||||
NonnullRefPtrVector<FileDescription>& sendfd_queue_for(const FileDescription&);
|
NonnullRefPtrVector<FileDescription>& sendfd_queue_for(const FileDescription&);
|
||||||
NonnullRefPtrVector<FileDescription>& recvfd_queue_for(const FileDescription&);
|
NonnullRefPtrVector<FileDescription>& recvfd_queue_for(const FileDescription&);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue