mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:27:35 +00:00
Kernel: Convert KBuffer::copy() => KBuffer::try_copy()
This was a weird KBuffer API that assumed failure was impossible. This patch converts it to a modern KResultOr<NonnullOwnPtr<KBuffer>> API and updates the two clients to the new style.
This commit is contained in:
parent
250b52d6e5
commit
b300f9aa2f
5 changed files with 49 additions and 28 deletions
|
@ -122,9 +122,12 @@ public:
|
||||||
return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull()));
|
return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull()));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static KBuffer copy(const void* data, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer")
|
static KResultOr<NonnullOwnPtr<KBuffer>> try_copy(const void* data, size_t size, Memory::Region::Access access = Memory::Region::Access::ReadWrite, StringView name = "KBuffer")
|
||||||
{
|
{
|
||||||
return KBuffer(KBufferImpl::copy(data, size, access, name));
|
auto impl = KBufferImpl::copy(data, size, access, name);
|
||||||
|
if (!impl)
|
||||||
|
return ENOMEM;
|
||||||
|
return adopt_nonnull_own_or_enomem(new (nothrow) KBuffer(impl.release_nonnull()));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool is_null() const { return !m_impl; }
|
[[nodiscard]] bool is_null() const { return !m_impl; }
|
||||||
|
|
|
@ -17,7 +17,7 @@ typedef void* (*ModuleFiniPtr)();
|
||||||
|
|
||||||
struct Module {
|
struct Module {
|
||||||
String name;
|
String name;
|
||||||
Vector<KBuffer> sections;
|
NonnullOwnPtrVector<KBuffer> sections;
|
||||||
|
|
||||||
ModuleInitPtr module_init { nullptr };
|
ModuleInitPtr module_init { nullptr };
|
||||||
ModuleFiniPtr module_fini { nullptr };
|
ModuleFiniPtr module_fini { nullptr };
|
||||||
|
|
|
@ -284,7 +284,8 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& descrip
|
||||||
KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, Time& packet_timestamp)
|
KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, Time& packet_timestamp)
|
||||||
{
|
{
|
||||||
MutexLocker locker(mutex());
|
MutexLocker locker(mutex());
|
||||||
ReceivedPacket packet;
|
ReceivedPacket taken_packet;
|
||||||
|
ReceivedPacket* packet { nullptr };
|
||||||
{
|
{
|
||||||
if (m_receive_queue.is_empty()) {
|
if (m_receive_queue.is_empty()) {
|
||||||
// FIXME: Shouldn't this return ENOTCONN instead of EOF?
|
// FIXME: Shouldn't this return ENOTCONN instead of EOF?
|
||||||
|
@ -296,20 +297,22 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_receive_queue.is_empty()) {
|
if (!m_receive_queue.is_empty()) {
|
||||||
if (flags & MSG_PEEK)
|
if (flags & MSG_PEEK) {
|
||||||
packet = m_receive_queue.first();
|
packet = &m_receive_queue.first();
|
||||||
else
|
} else {
|
||||||
packet = m_receive_queue.take_first();
|
taken_packet = m_receive_queue.take_first();
|
||||||
|
packet = &taken_packet;
|
||||||
|
}
|
||||||
|
|
||||||
set_can_read(!m_receive_queue.is_empty());
|
set_can_read(!m_receive_queue.is_empty());
|
||||||
|
|
||||||
dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom without blocking {} bytes, packets in queue: {}",
|
dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom without blocking {} bytes, packets in queue: {}",
|
||||||
this,
|
this,
|
||||||
packet.data.value().size(),
|
packet->data->size(),
|
||||||
m_receive_queue.size());
|
m_receive_queue.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!packet.data.has_value()) {
|
if (!packet->data) {
|
||||||
if (protocol_is_disconnected()) {
|
if (protocol_is_disconnected()) {
|
||||||
dbgln("IPv4Socket({}) is protocol-disconnected, returning 0 in recvfrom!", this);
|
dbgln("IPv4Socket({}) is protocol-disconnected, returning 0 in recvfrom!", this);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -330,28 +333,30 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr
|
||||||
VERIFY(m_can_read);
|
VERIFY(m_can_read);
|
||||||
VERIFY(!m_receive_queue.is_empty());
|
VERIFY(!m_receive_queue.is_empty());
|
||||||
|
|
||||||
if (flags & MSG_PEEK)
|
if (flags & MSG_PEEK) {
|
||||||
packet = m_receive_queue.first();
|
packet = &m_receive_queue.first();
|
||||||
else
|
} else {
|
||||||
packet = m_receive_queue.take_first();
|
taken_packet = m_receive_queue.take_first();
|
||||||
|
packet = &taken_packet;
|
||||||
|
}
|
||||||
|
|
||||||
set_can_read(!m_receive_queue.is_empty());
|
set_can_read(!m_receive_queue.is_empty());
|
||||||
|
|
||||||
dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom with blocking {} bytes, packets in queue: {}",
|
dbgln_if(IPV4_SOCKET_DEBUG, "IPv4Socket({}): recvfrom with blocking {} bytes, packets in queue: {}",
|
||||||
this,
|
this,
|
||||||
packet.data.value().size(),
|
packet->data->size(),
|
||||||
m_receive_queue.size());
|
m_receive_queue.size());
|
||||||
}
|
}
|
||||||
VERIFY(packet.data.has_value());
|
VERIFY(packet->data);
|
||||||
|
|
||||||
packet_timestamp = packet.timestamp;
|
packet_timestamp = packet->timestamp;
|
||||||
|
|
||||||
if (addr) {
|
if (addr) {
|
||||||
dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet.peer_address, packet.peer_port);
|
dbgln_if(IPV4_SOCKET_DEBUG, "Incoming packet is from: {}:{}", packet->peer_address, packet->peer_port);
|
||||||
|
|
||||||
sockaddr_in out_addr {};
|
sockaddr_in out_addr {};
|
||||||
memcpy(&out_addr.sin_addr, &packet.peer_address, sizeof(IPv4Address));
|
memcpy(&out_addr.sin_addr, &packet->peer_address, sizeof(IPv4Address));
|
||||||
out_addr.sin_port = htons(packet.peer_port);
|
out_addr.sin_port = htons(packet->peer_port);
|
||||||
out_addr.sin_family = AF_INET;
|
out_addr.sin_family = AF_INET;
|
||||||
Userspace<sockaddr_in*> dest_addr = addr.ptr();
|
Userspace<sockaddr_in*> dest_addr = addr.ptr();
|
||||||
SOCKET_TRY(copy_to_user(dest_addr, &out_addr));
|
SOCKET_TRY(copy_to_user(dest_addr, &out_addr));
|
||||||
|
@ -362,12 +367,12 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type() == SOCK_RAW) {
|
if (type() == SOCK_RAW) {
|
||||||
size_t bytes_written = min(packet.data.value().size(), buffer_length);
|
size_t bytes_written = min(packet->data->size(), buffer_length);
|
||||||
SOCKET_TRY(buffer.write(packet.data.value().data(), bytes_written));
|
SOCKET_TRY(buffer.write(packet->data->data(), bytes_written));
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
return protocol_receive(ReadonlyBytes { packet.data.value().data(), packet.data.value().size() }, buffer, buffer_length, flags);
|
return protocol_receive(ReadonlyBytes { packet->data->data(), packet->data->size() }, buffer, buffer_length, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, Time& packet_timestamp)
|
KResultOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, Time& packet_timestamp)
|
||||||
|
@ -421,7 +426,12 @@ bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port,
|
||||||
dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this);
|
dbgln("IPv4Socket({}): did_receive refusing packet since queue is full.", this);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_receive_queue.append({ source_address, source_port, packet_timestamp, KBuffer::copy(packet.data(), packet.size()) });
|
auto data_or_error = KBuffer::try_copy(packet.data(), packet.size());
|
||||||
|
if (data_or_error.is_error()) {
|
||||||
|
dbgln("IPv4Socket: did_receive unable to allocate storage for incoming packet.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_receive_queue.append({ source_address, source_port, packet_timestamp, data_or_error.release_value() });
|
||||||
set_can_read(true);
|
set_can_read(true);
|
||||||
}
|
}
|
||||||
m_bytes_received += packet_size;
|
m_bytes_received += packet_size;
|
||||||
|
|
|
@ -110,7 +110,7 @@ private:
|
||||||
IPv4Address peer_address;
|
IPv4Address peer_address;
|
||||||
u16 peer_port;
|
u16 peer_port;
|
||||||
Time timestamp;
|
Time timestamp;
|
||||||
Optional<KBuffer> data;
|
OwnPtr<KBuffer> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
SinglyLinkedListWithCount<ReceivedPacket> m_receive_queue;
|
SinglyLinkedListWithCount<ReceivedPacket> m_receive_queue;
|
||||||
|
|
|
@ -41,13 +41,21 @@ KResultOr<FlatPtr> Process::sys$module_load(Userspace<const char*> user_path, si
|
||||||
if (!module)
|
if (!module)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
KResult section_loading_result = KSuccess;
|
||||||
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) {
|
elf_image->for_each_section_of_type(SHT_PROGBITS, [&](const ELF::Image::Section& section) {
|
||||||
if (!section.size())
|
if (!section.size() || !section_loading_result.is_error())
|
||||||
return;
|
return;
|
||||||
auto section_storage = KBuffer::copy(section.raw_data(), section.size(), Memory::Region::Access::ReadWriteExecute);
|
auto section_storage_or_error = KBuffer::try_copy(section.raw_data(), section.size(), Memory::Region::Access::ReadWriteExecute);
|
||||||
section_storage_by_name.set(section.name(), section_storage.data());
|
if (section_storage_or_error.is_error()) {
|
||||||
|
section_loading_result = section_storage_or_error.error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto section_storage = section_storage_or_error.release_value();
|
||||||
|
section_storage_by_name.set(section.name(), section_storage->data());
|
||||||
module->sections.append(move(section_storage));
|
module->sections.append(move(section_storage));
|
||||||
});
|
});
|
||||||
|
if (section_loading_result.is_error())
|
||||||
|
return section_loading_result;
|
||||||
|
|
||||||
bool missing_symbols = false;
|
bool missing_symbols = false;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue