mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 07:47:37 +00:00
Kernel: Make File::write() and File::read() return KResultOr<size_t>
Instead of returning a ssize_t where negative values mean error, we now return KResultOr<size_t> and use the error state to report errors exclusively.
This commit is contained in:
parent
58feebeed2
commit
7a3ab6c517
58 changed files with 223 additions and 229 deletions
|
@ -193,16 +193,16 @@ int IPv4Socket::allocate_local_port_if_needed()
|
|||
return port;
|
||||
}
|
||||
|
||||
ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_length, int flags, const sockaddr* addr, socklen_t addr_length)
|
||||
KResultOr<size_t> IPv4Socket::sendto(FileDescription&, const void* data, size_t data_length, int flags, const sockaddr* addr, socklen_t addr_length)
|
||||
{
|
||||
(void)flags;
|
||||
if (addr && addr_length != sizeof(sockaddr_in))
|
||||
return -EINVAL;
|
||||
return KResult(-EINVAL);
|
||||
|
||||
if (addr) {
|
||||
if (addr->sa_family != AF_INET) {
|
||||
klog() << "sendto: Bad address family: " << addr->sa_family << " is not AF_INET!";
|
||||
return -EAFNOSUPPORT;
|
||||
return KResult(-EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
auto& ia = *(const sockaddr_in*)addr;
|
||||
|
@ -212,7 +212,7 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt
|
|||
|
||||
auto routing_decision = route_to(m_peer_address, m_local_address, bound_interface());
|
||||
if (routing_decision.is_zero())
|
||||
return -EHOSTUNREACH;
|
||||
return KResult(-EHOSTUNREACH);
|
||||
|
||||
if (m_local_address.to_u32() == 0)
|
||||
m_local_address = routing_decision.adapter->ipv4_address();
|
||||
|
@ -230,20 +230,20 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt
|
|||
return data_length;
|
||||
}
|
||||
|
||||
int nsent = protocol_send(data, data_length);
|
||||
if (nsent > 0)
|
||||
Thread::current()->did_ipv4_socket_write(nsent);
|
||||
return nsent;
|
||||
auto nsent_or_error = protocol_send(data, data_length);
|
||||
if (!nsent_or_error.is_error())
|
||||
Thread::current()->did_ipv4_socket_write(nsent_or_error.value());
|
||||
return nsent_or_error;
|
||||
}
|
||||
|
||||
ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* buffer, size_t buffer_length, int, sockaddr*, socklen_t*)
|
||||
KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description, void* buffer, size_t buffer_length, int, sockaddr*, socklen_t*)
|
||||
{
|
||||
Locker locker(lock());
|
||||
if (m_receive_buffer.is_empty()) {
|
||||
if (protocol_is_disconnected())
|
||||
return 0;
|
||||
if (!description.is_blocking())
|
||||
return -EAGAIN;
|
||||
return KResult(-EAGAIN);
|
||||
|
||||
locker.unlock();
|
||||
auto res = Thread::current()->block<Thread::ReadBlocker>(nullptr, description);
|
||||
|
@ -251,10 +251,10 @@ ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* bu
|
|||
|
||||
if (!m_can_read) {
|
||||
if (res.was_interrupted())
|
||||
return -EINTR;
|
||||
return KResult(-EINTR);
|
||||
|
||||
// Unblocked due to timeout.
|
||||
return -EAGAIN;
|
||||
return KResult(-EAGAIN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* bu
|
|||
return nreceived;
|
||||
}
|
||||
|
||||
ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
|
||||
KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
|
||||
{
|
||||
Locker locker(lock());
|
||||
ReceivedPacket packet;
|
||||
|
@ -278,7 +278,7 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
|
|||
if (protocol_is_disconnected())
|
||||
return 0;
|
||||
if (!description.is_blocking())
|
||||
return -EAGAIN;
|
||||
return KResult(-EAGAIN);
|
||||
}
|
||||
|
||||
if (!m_receive_queue.is_empty()) {
|
||||
|
@ -301,10 +301,10 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
|
|||
|
||||
if (!m_can_read) {
|
||||
if (res.was_interrupted())
|
||||
return -EINTR;
|
||||
return KResult(-EINTR);
|
||||
|
||||
// Unblocked due to timeout.
|
||||
return -EAGAIN;
|
||||
return KResult(-EAGAIN);
|
||||
}
|
||||
ASSERT(m_can_read);
|
||||
ASSERT(!m_receive_queue.is_empty());
|
||||
|
@ -338,23 +338,23 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
|
|||
return protocol_receive(packet.data.value(), buffer, buffer_length, flags);
|
||||
}
|
||||
|
||||
ssize_t IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
|
||||
KResultOr<size_t> IPv4Socket::recvfrom(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length)
|
||||
{
|
||||
if (addr_length && *addr_length < sizeof(sockaddr_in))
|
||||
return -EINVAL;
|
||||
return KResult(-EINVAL);
|
||||
|
||||
#ifdef IPV4_SOCKET_DEBUG
|
||||
klog() << "recvfrom: type=" << type() << ", local_port=" << local_port();
|
||||
#endif
|
||||
|
||||
ssize_t nreceived = 0;
|
||||
KResultOr<size_t> nreceived = 0;
|
||||
if (buffer_mode() == BufferMode::Bytes)
|
||||
nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, addr, addr_length);
|
||||
else
|
||||
nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, addr, addr_length);
|
||||
|
||||
if (nreceived > 0)
|
||||
Thread::current()->did_ipv4_socket_read(nreceived);
|
||||
if (!nreceived.is_error())
|
||||
Thread::current()->did_ipv4_socket_read(nreceived.value());
|
||||
return nreceived;
|
||||
}
|
||||
|
||||
|
@ -374,8 +374,10 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port,
|
|||
ASSERT(m_can_read);
|
||||
return false;
|
||||
}
|
||||
int nreceived = protocol_receive(packet, m_scratch_buffer.value().data(), m_scratch_buffer.value().size(), 0);
|
||||
m_receive_buffer.write(m_scratch_buffer.value().data(), nreceived);
|
||||
auto nreceived_or_error = protocol_receive(packet, m_scratch_buffer.value().data(), m_scratch_buffer.value().size(), 0);
|
||||
if (nreceived_or_error.is_error())
|
||||
return false;
|
||||
m_receive_buffer.write(m_scratch_buffer.value().data(), nreceived_or_error.value());
|
||||
m_can_read = !m_receive_buffer.is_empty();
|
||||
} else {
|
||||
// FIXME: Maybe track the number of packets so we don't have to walk the entire packet queue to count them..
|
||||
|
|
|
@ -58,8 +58,8 @@ public:
|
|||
virtual void detach(FileDescription&) override;
|
||||
virtual bool can_read(const FileDescription&, size_t) const override;
|
||||
virtual bool can_write(const FileDescription&, size_t) const override;
|
||||
virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
|
||||
virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
|
||||
virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
|
||||
virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
|
||||
virtual KResult setsockopt(int level, int option, const void*, socklen_t) override;
|
||||
virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override;
|
||||
|
||||
|
@ -96,8 +96,8 @@ protected:
|
|||
|
||||
virtual KResult protocol_bind() { return KSuccess; }
|
||||
virtual KResult protocol_listen() { return KSuccess; }
|
||||
virtual int protocol_receive(const KBuffer&, void*, size_t, int) { return -ENOTIMPL; }
|
||||
virtual int protocol_send(const void*, size_t) { return -ENOTIMPL; }
|
||||
virtual KResultOr<size_t> protocol_receive(const KBuffer&, void*, size_t, int) { return -ENOTIMPL; }
|
||||
virtual KResultOr<size_t> protocol_send(const void*, size_t) { return -ENOTIMPL; }
|
||||
virtual KResult protocol_connect(FileDescription&, ShouldBlock) { return KSuccess; }
|
||||
virtual int protocol_allocate_local_port() { return 0; }
|
||||
virtual bool protocol_is_disconnected() const { return false; }
|
||||
|
@ -110,8 +110,8 @@ protected:
|
|||
private:
|
||||
virtual bool is_ipv4() const override { return true; }
|
||||
|
||||
ssize_t receive_byte_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
|
||||
ssize_t receive_packet_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
|
||||
KResultOr<size_t> receive_byte_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
|
||||
KResultOr<size_t> receive_packet_buffered(FileDescription&, void* buffer, size_t buffer_length, int flags, sockaddr*, socklen_t*);
|
||||
|
||||
IPv4Address m_local_address;
|
||||
IPv4Address m_peer_address;
|
||||
|
|
|
@ -260,10 +260,10 @@ bool LocalSocket::can_write(const FileDescription& description, size_t) const
|
|||
return false;
|
||||
}
|
||||
|
||||
ssize_t LocalSocket::sendto(FileDescription& description, const void* data, size_t data_size, int, const sockaddr*, socklen_t)
|
||||
KResultOr<size_t> LocalSocket::sendto(FileDescription& description, const void* data, size_t data_size, int, const sockaddr*, socklen_t)
|
||||
{
|
||||
if (!has_attached_peer(description))
|
||||
return -EPIPE;
|
||||
return KResult(-EPIPE);
|
||||
ssize_t nwritten = send_buffer_for(description).write((const u8*)data, data_size);
|
||||
if (nwritten > 0)
|
||||
Thread::current()->did_unix_socket_write(nwritten);
|
||||
|
@ -290,18 +290,18 @@ DoubleBuffer& LocalSocket::send_buffer_for(FileDescription& description)
|
|||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ssize_t LocalSocket::recvfrom(FileDescription& description, void* buffer, size_t buffer_size, int, sockaddr*, socklen_t*)
|
||||
KResultOr<size_t> LocalSocket::recvfrom(FileDescription& description, void* buffer, size_t buffer_size, int, sockaddr*, socklen_t*)
|
||||
{
|
||||
auto& buffer_for_me = receive_buffer_for(description);
|
||||
if (!description.is_blocking()) {
|
||||
if (buffer_for_me.is_empty()) {
|
||||
if (!has_attached_peer(description))
|
||||
return 0;
|
||||
return -EAGAIN;
|
||||
return KResult(-EAGAIN);
|
||||
}
|
||||
} else if (!can_read(description, 0)) {
|
||||
if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description).was_interrupted())
|
||||
return -EINTR;
|
||||
return KResult(-EINTR);
|
||||
}
|
||||
if (!has_attached_peer(description) && buffer_for_me.is_empty())
|
||||
return 0;
|
||||
|
|
|
@ -60,8 +60,8 @@ public:
|
|||
virtual void detach(FileDescription&) override;
|
||||
virtual bool can_read(const FileDescription&, size_t) const override;
|
||||
virtual bool can_write(const FileDescription&, size_t) const override;
|
||||
virtual ssize_t sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
|
||||
virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
|
||||
virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int, const sockaddr*, socklen_t) override;
|
||||
virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) override;
|
||||
virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*) override;
|
||||
virtual KResult chown(FileDescription&, uid_t, gid_t) override;
|
||||
virtual KResult chmod(FileDescription&, mode_t) override;
|
||||
|
|
|
@ -178,14 +178,14 @@ KResult Socket::getsockopt(FileDescription&, int level, int option, void* value,
|
|||
}
|
||||
}
|
||||
|
||||
ssize_t Socket::read(FileDescription& description, size_t, u8* buffer, ssize_t size)
|
||||
KResultOr<size_t> Socket::read(FileDescription& description, size_t, u8* buffer, size_t size)
|
||||
{
|
||||
if (is_shut_down_for_reading())
|
||||
return 0;
|
||||
return recvfrom(description, buffer, size, 0, nullptr, 0);
|
||||
}
|
||||
|
||||
ssize_t Socket::write(FileDescription& description, size_t, const u8* data, ssize_t size)
|
||||
KResultOr<size_t> Socket::write(FileDescription& description, size_t, const u8* data, size_t size)
|
||||
{
|
||||
if (is_shut_down_for_writing())
|
||||
return -EPIPE;
|
||||
|
|
|
@ -107,8 +107,8 @@ public:
|
|||
virtual bool is_ipv4() const { return false; }
|
||||
virtual void attach(FileDescription&) = 0;
|
||||
virtual void detach(FileDescription&) = 0;
|
||||
virtual ssize_t sendto(FileDescription&, const void*, size_t, int flags, const sockaddr*, socklen_t) = 0;
|
||||
virtual ssize_t recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) = 0;
|
||||
virtual KResultOr<size_t> sendto(FileDescription&, const void*, size_t, int flags, const sockaddr*, socklen_t) = 0;
|
||||
virtual KResultOr<size_t> recvfrom(FileDescription&, void*, size_t, int flags, sockaddr*, socklen_t*) = 0;
|
||||
|
||||
virtual KResult setsockopt(int level, int option, const void*, socklen_t);
|
||||
virtual KResult getsockopt(FileDescription&, int level, int option, void*, socklen_t*);
|
||||
|
@ -124,8 +124,8 @@ public:
|
|||
Lock& lock() { return m_lock; }
|
||||
|
||||
// ^File
|
||||
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override final;
|
||||
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override final;
|
||||
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override final;
|
||||
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override final;
|
||||
virtual String absolute_path(const FileDescription&) const override = 0;
|
||||
|
||||
bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; }
|
||||
|
|
|
@ -161,7 +161,7 @@ NonnullRefPtr<TCPSocket> TCPSocket::create(int protocol)
|
|||
return adopt(*new TCPSocket(protocol));
|
||||
}
|
||||
|
||||
int TCPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags)
|
||||
KResultOr<size_t> TCPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags)
|
||||
{
|
||||
(void)flags;
|
||||
auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.data());
|
||||
|
@ -175,7 +175,7 @@ int TCPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size
|
|||
return payload_size;
|
||||
}
|
||||
|
||||
int TCPSocket::protocol_send(const void* data, size_t data_length)
|
||||
KResultOr<size_t> TCPSocket::protocol_send(const void* data, size_t data_length)
|
||||
{
|
||||
send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, data, data_length);
|
||||
return data_length;
|
||||
|
|
|
@ -178,8 +178,8 @@ private:
|
|||
|
||||
virtual void shut_down_for_writing() override;
|
||||
|
||||
virtual int protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
|
||||
virtual int protocol_send(const void*, size_t) override;
|
||||
virtual KResultOr<size_t> protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
|
||||
virtual KResultOr<size_t> protocol_send(const void*, size_t) override;
|
||||
virtual KResult protocol_connect(FileDescription&, ShouldBlock) override;
|
||||
virtual int protocol_allocate_local_port() override;
|
||||
virtual bool protocol_is_disconnected() const override;
|
||||
|
|
|
@ -79,7 +79,7 @@ NonnullRefPtr<UDPSocket> UDPSocket::create(int protocol)
|
|||
return adopt(*new UDPSocket(protocol));
|
||||
}
|
||||
|
||||
int UDPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags)
|
||||
KResultOr<size_t> UDPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size_t buffer_size, int flags)
|
||||
{
|
||||
(void)flags;
|
||||
auto& ipv4_packet = *(const IPv4Packet*)(packet_buffer.data());
|
||||
|
@ -90,11 +90,11 @@ int UDPSocket::protocol_receive(const KBuffer& packet_buffer, void* buffer, size
|
|||
return udp_packet.length() - sizeof(UDPPacket);
|
||||
}
|
||||
|
||||
int UDPSocket::protocol_send(const void* data, size_t data_length)
|
||||
KResultOr<size_t> UDPSocket::protocol_send(const void* data, size_t data_length)
|
||||
{
|
||||
auto routing_decision = route_to(peer_address(), local_address(), bound_interface());
|
||||
if (routing_decision.is_zero())
|
||||
return -EHOSTUNREACH;
|
||||
return KResult(-EHOSTUNREACH);
|
||||
auto buffer = ByteBuffer::create_zeroed(sizeof(UDPPacket) + data_length);
|
||||
auto& udp_packet = *(UDPPacket*)(buffer.data());
|
||||
udp_packet.set_source_port(local_port());
|
||||
|
|
|
@ -43,8 +43,8 @@ private:
|
|||
virtual const char* class_name() const override { return "UDPSocket"; }
|
||||
static Lockable<HashMap<u16, UDPSocket*>>& sockets_by_port();
|
||||
|
||||
virtual int protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
|
||||
virtual int protocol_send(const void*, size_t) override;
|
||||
virtual KResultOr<size_t> protocol_receive(const KBuffer&, void* buffer, size_t buffer_size, int flags) override;
|
||||
virtual KResultOr<size_t> protocol_send(const void*, size_t) override;
|
||||
virtual KResult protocol_connect(FileDescription&, ShouldBlock) override;
|
||||
virtual int protocol_allocate_local_port() override;
|
||||
virtual KResult protocol_bind() override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue