LibIPC+LibWeb: Introduce IPC::Attachment abstraction
Replace IPC::File / AutoCloseFileDescriptor / MessageFileType in the IPC message pipeline with a new IPC::Attachment class. This wraps a file descriptor transferred alongside IPC messages, and provides a clean extension point for platform-specific transport mechanisms (e.g., Mach ports on macOS) that will be introduced later.
This commit is contained in:
parent
d094de39fc
commit
da6b928909
20 changed files with 162 additions and 78 deletions
45
Libraries/LibIPC/Attachment.cpp
Normal file
45
Libraries/LibIPC/Attachment.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
|
||||
namespace IPC {
|
||||
|
||||
Attachment::Attachment(Attachment&& other)
|
||||
: m_fd(exchange(other.m_fd, -1))
|
||||
{
|
||||
}
|
||||
|
||||
Attachment& Attachment::operator=(Attachment&& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
if (m_fd != -1)
|
||||
(void)Core::System::close(m_fd);
|
||||
m_fd = exchange(other.m_fd, -1);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Attachment::~Attachment()
|
||||
{
|
||||
if (m_fd != -1)
|
||||
(void)Core::System::close(m_fd);
|
||||
}
|
||||
|
||||
Attachment Attachment::from_fd(int fd)
|
||||
{
|
||||
Attachment attachment;
|
||||
attachment.m_fd = fd;
|
||||
return attachment;
|
||||
}
|
||||
|
||||
int Attachment::to_fd()
|
||||
{
|
||||
return exchange(m_fd, -1);
|
||||
}
|
||||
|
||||
}
|
||||
29
Libraries/LibIPC/Attachment.h
Normal file
29
Libraries/LibIPC/Attachment.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Noncopyable.h>
|
||||
|
||||
namespace IPC {
|
||||
|
||||
class Attachment {
|
||||
AK_MAKE_NONCOPYABLE(Attachment);
|
||||
|
||||
public:
|
||||
Attachment() = default;
|
||||
Attachment(Attachment&&);
|
||||
Attachment& operator=(Attachment&&);
|
||||
~Attachment();
|
||||
|
||||
static Attachment from_fd(int fd);
|
||||
int to_fd();
|
||||
|
||||
private:
|
||||
int m_fd { -1 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -8,11 +8,13 @@ set(SOURCES
|
|||
|
||||
if (UNIX)
|
||||
list(APPEND SOURCES
|
||||
Attachment.cpp
|
||||
File.cpp
|
||||
Message.cpp
|
||||
TransportSocket.cpp)
|
||||
else()
|
||||
list(APPEND SOURCES
|
||||
Attachment.cpp
|
||||
FileWindows.cpp
|
||||
MessageWindows.cpp
|
||||
TransportSocketWindows.cpp)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ ConnectionBase::PeerEOF ConnectionBase::drain_messages_from_peer()
|
|||
{
|
||||
bool parse_error = false;
|
||||
auto schedule_shutdown = m_transport->read_as_many_messages_as_possible_without_blocking([&](auto&& raw_message) {
|
||||
if (auto message = try_parse_message(raw_message.bytes, raw_message.fds)) {
|
||||
if (auto message = try_parse_message(raw_message.bytes, raw_message.attachments)) {
|
||||
m_unprocessed_messages.append(message.release_nonnull());
|
||||
} else {
|
||||
dbgln("Failed to parse IPC message {:hex-dump}", raw_message.bytes);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <AK/Forward.h>
|
||||
#include <AK/Queue.h>
|
||||
#include <LibCore/EventReceiver.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibIPC/Message.h>
|
||||
#include <LibIPC/Transport.h>
|
||||
|
|
@ -37,7 +37,7 @@ protected:
|
|||
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Transport>, u32 local_endpoint_magic);
|
||||
|
||||
virtual void shutdown_with_error(Error const&);
|
||||
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, Queue<File>&) = 0;
|
||||
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, Queue<Attachment>&) = 0;
|
||||
|
||||
OwnPtr<IPC::Message> wait_for_specific_endpoint_message_impl(u32 endpoint_magic, int message_id);
|
||||
void wait_for_transport_to_become_readable();
|
||||
|
|
@ -92,13 +92,13 @@ protected:
|
|||
return {};
|
||||
}
|
||||
|
||||
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, Queue<File>& fds) override
|
||||
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, Queue<Attachment>& attachments) override
|
||||
{
|
||||
auto local_message = LocalEndpoint::decode_message(bytes, fds);
|
||||
auto local_message = LocalEndpoint::decode_message(bytes, attachments);
|
||||
if (!local_message.is_error())
|
||||
return local_message.release_value();
|
||||
|
||||
auto peer_message = PeerEndpoint::decode_message(bytes, fds);
|
||||
auto peer_message = PeerEndpoint::decode_message(bytes, attachments);
|
||||
if (!peer_message.is_error())
|
||||
return peer_message.release_value();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <AK/Variant.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibCore/SharedCircularQueue.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Concepts.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
|
|
@ -37,9 +38,9 @@ inline ErrorOr<T> decode(Decoder&)
|
|||
|
||||
class Decoder {
|
||||
public:
|
||||
Decoder(Stream& stream, Queue<File>& files)
|
||||
Decoder(Stream& stream, Queue<Attachment>& attachments)
|
||||
: m_stream(stream)
|
||||
, m_files(files)
|
||||
, m_attachments(attachments)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -62,11 +63,11 @@ public:
|
|||
ErrorOr<size_t> decode_size();
|
||||
|
||||
Stream& stream() { return m_stream; }
|
||||
Queue<File>& files() { return m_files; }
|
||||
Queue<Attachment>& attachments() { return m_attachments; }
|
||||
|
||||
private:
|
||||
Stream& m_stream;
|
||||
Queue<File>& m_files;
|
||||
Queue<Attachment>& m_attachments;
|
||||
};
|
||||
|
||||
template<Arithmetic T>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <AK/Utf16View.h>
|
||||
#include <LibCore/AnonymousBuffer.h>
|
||||
#include <LibCore/Proxy.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibURL/Origin.h>
|
||||
|
|
@ -173,7 +174,7 @@ ErrorOr<void> encode(Encoder& encoder, File const& file)
|
|||
int fd = file.take_fd();
|
||||
VERIFY(fd >= 0);
|
||||
|
||||
TRY(encoder.append_file_descriptor(fd));
|
||||
TRY(encoder.append_attachment(Attachment::from_fd(fd)));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <AK/Variant.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibCore/SharedCircularQueue.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Concepts.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
|
|
@ -51,9 +52,9 @@ public:
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> append_file_descriptor(int fd)
|
||||
ErrorOr<void> append_attachment(Attachment attachment)
|
||||
{
|
||||
TRY(m_buffer.append_file_descriptor(fd));
|
||||
TRY(m_buffer.append_attachment(move(attachment)));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/File.h>
|
||||
|
||||
|
|
@ -63,9 +64,12 @@ ErrorOr<void> File::clear_close_on_exec()
|
|||
template<>
|
||||
ErrorOr<File> decode(Decoder& decoder)
|
||||
{
|
||||
auto file = TRY(decoder.files().try_dequeue());
|
||||
TRY(Core::System::set_close_on_exec(file.fd(), true));
|
||||
return file;
|
||||
auto attachment = TRY(decoder.attachments().try_dequeue());
|
||||
int fd = attachment.to_fd();
|
||||
if (fd < 0)
|
||||
return Error::from_string_literal("Failed to obtain fd from attachment");
|
||||
TRY(Core::System::set_close_on_exec(fd, true));
|
||||
return File::adopt_fd(fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
namespace IPC {
|
||||
|
||||
class Attachment;
|
||||
class AutoCloseFileDescriptor;
|
||||
class Decoder;
|
||||
class Encoder;
|
||||
|
|
@ -26,6 +27,5 @@ template<typename T>
|
|||
ErrorOr<T> decode(Decoder&);
|
||||
|
||||
using MessageDataType = Vector<u8, 1024>;
|
||||
using MessageFileType = Vector<NonnullRefPtr<AutoCloseFileDescriptor>, 1>;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,26 +27,29 @@ ErrorOr<void> MessageBuffer::append_data(u8 const* values, size_t count)
|
|||
|
||||
ErrorOr<void> MessageBuffer::append_file_descriptor(int fd)
|
||||
{
|
||||
auto auto_fd = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AutoCloseFileDescriptor(fd)));
|
||||
TRY(m_fds.try_append(move(auto_fd)));
|
||||
TRY(m_attachments.try_append(Attachment::from_fd(fd)));
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> MessageBuffer::append_attachment(Attachment attachment)
|
||||
{
|
||||
TRY(m_attachments.try_append(move(attachment)));
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> MessageBuffer::extend(MessageBuffer&& buffer)
|
||||
{
|
||||
TRY(m_data.try_extend(move(buffer.m_data)));
|
||||
TRY(m_fds.try_extend(move(buffer.m_fds)));
|
||||
TRY(m_attachments.try_extend(move(buffer.m_attachments)));
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> MessageBuffer::transfer_message(Transport& transport)
|
||||
{
|
||||
// These VERIFYs catch bugs where we try to send messages that exceed IPC limits.
|
||||
// If we hit these, we have a bug in our encoding code.
|
||||
VERIFY(m_data.size() <= MAX_MESSAGE_PAYLOAD_SIZE);
|
||||
VERIFY(m_fds.size() <= MAX_MESSAGE_FD_COUNT);
|
||||
VERIFY(m_attachments.size() <= MAX_MESSAGE_FD_COUNT);
|
||||
|
||||
transport.post_message(m_data, m_fds);
|
||||
transport.post_message(m_data, m_attachments);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibIPC/AutoCloseFileDescriptor.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibIPC/Transport.h>
|
||||
|
||||
|
|
@ -19,9 +19,9 @@ class MessageBuffer {
|
|||
public:
|
||||
MessageBuffer();
|
||||
|
||||
MessageBuffer(MessageDataType data, MessageFileType fds)
|
||||
MessageBuffer(MessageDataType data, Vector<Attachment> attachments)
|
||||
: m_data(move(data))
|
||||
, m_fds(move(fds))
|
||||
, m_attachments(move(attachments))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -29,6 +29,7 @@ public:
|
|||
ErrorOr<void> append_data(u8 const* values, size_t count);
|
||||
|
||||
ErrorOr<void> append_file_descriptor(int fd);
|
||||
ErrorOr<void> append_attachment(Attachment);
|
||||
|
||||
ErrorOr<void> extend(MessageBuffer&& buffer);
|
||||
|
||||
|
|
@ -37,12 +38,12 @@ public:
|
|||
MessageDataType const& data() const { return m_data; }
|
||||
MessageDataType take_data() { return move(m_data); }
|
||||
|
||||
MessageFileType const& fds() const { return m_fds; }
|
||||
MessageFileType take_fds() { return move(m_fds); }
|
||||
Vector<Attachment> const& attachments() const { return m_attachments; }
|
||||
Vector<Attachment> take_attachments() { return move(m_attachments); }
|
||||
|
||||
private:
|
||||
MessageDataType m_data;
|
||||
MessageFileType m_fds;
|
||||
Vector<Attachment> m_attachments;
|
||||
#ifdef AK_OS_WINDOWS
|
||||
Vector<size_t> m_handle_offsets;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ ErrorOr<void> MessageBuffer::append_data(u8 const* values, size_t count)
|
|||
|
||||
ErrorOr<void> MessageBuffer::append_file_descriptor(int handle)
|
||||
{
|
||||
TRY(m_fds.try_append(adopt_ref(*new AutoCloseFileDescriptor(handle))));
|
||||
TRY(m_handle_offsets.try_append(m_data.size()));
|
||||
|
||||
if (Core::System::is_socket(handle)) {
|
||||
|
|
@ -56,10 +55,15 @@ ErrorOr<void> MessageBuffer::append_file_descriptor(int handle)
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> MessageBuffer::append_attachment(Attachment attachment)
|
||||
{
|
||||
return append_file_descriptor(attachment.to_fd());
|
||||
}
|
||||
|
||||
ErrorOr<void> MessageBuffer::extend(MessageBuffer&& buffer)
|
||||
{
|
||||
TRY(m_data.try_extend(move(buffer.m_data)));
|
||||
TRY(m_fds.try_extend(move(buffer.m_fds)));
|
||||
TRY(m_attachments.try_extend(move(buffer.m_attachments)));
|
||||
TRY(m_handle_offsets.try_extend(move(buffer.m_handle_offsets)));
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <AK/Types.h>
|
||||
#include <LibCore/Socket.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Limits.h>
|
||||
#include <LibIPC/TransportSocket.h>
|
||||
#include <LibThreading/Thread.h>
|
||||
|
|
@ -249,9 +250,9 @@ struct MessageHeader {
|
|||
u32 fd_count { 0 };
|
||||
};
|
||||
|
||||
void TransportSocket::post_message(Vector<u8> const& bytes_to_write, Vector<NonnullRefPtr<AutoCloseFileDescriptor>> const& fds)
|
||||
void TransportSocket::post_message(Vector<u8> const& bytes_to_write, Vector<Attachment>& attachments)
|
||||
{
|
||||
auto num_fds_to_transfer = fds.size();
|
||||
auto num_fds_to_transfer = attachments.size();
|
||||
|
||||
MessageHeader header {
|
||||
.type = MessageHeader::Type::Payload,
|
||||
|
|
@ -259,17 +260,15 @@ void TransportSocket::post_message(Vector<u8> const& bytes_to_write, Vector<Nonn
|
|||
.fd_count = static_cast<u32>(num_fds_to_transfer),
|
||||
};
|
||||
|
||||
{
|
||||
Threading::MutexLocker locker(m_fds_retained_until_received_by_peer_mutex);
|
||||
for (auto const& fd : fds)
|
||||
m_fds_retained_until_received_by_peer.enqueue(fd);
|
||||
}
|
||||
|
||||
auto raw_fds = Vector<int, 1> {};
|
||||
if (num_fds_to_transfer > 0) {
|
||||
raw_fds.ensure_capacity(num_fds_to_transfer);
|
||||
for (auto const& owned_fd : fds) {
|
||||
raw_fds.unchecked_append(owned_fd->value());
|
||||
Threading::MutexLocker locker(m_fds_retained_until_received_by_peer_mutex);
|
||||
for (auto& attachment : attachments) {
|
||||
int fd = attachment.to_fd();
|
||||
auto auto_fd = adopt_ref(*new AutoCloseFileDescriptor(fd));
|
||||
raw_fds.unchecked_append(auto_fd->value());
|
||||
m_fds_retained_until_received_by_peer.enqueue(move(auto_fd));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -366,13 +365,13 @@ void TransportSocket::read_incoming_messages()
|
|||
m_peer_eof = true;
|
||||
break;
|
||||
}
|
||||
if (m_unprocessed_fds.size() + received_fds.size() > MAX_UNPROCESSED_FDS) {
|
||||
if (m_unprocessed_attachments.size() + received_fds.size() > MAX_UNPROCESSED_FDS) {
|
||||
dbgln("TransportSocket: Unprocessed FDs would exceed {}, disconnecting peer", MAX_UNPROCESSED_FDS);
|
||||
m_peer_eof = true;
|
||||
break;
|
||||
}
|
||||
for (auto const& fd : received_fds) {
|
||||
m_unprocessed_fds.enqueue(File::adopt_fd(fd));
|
||||
m_unprocessed_attachments.enqueue(Attachment::from_fd(fd));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,7 +396,7 @@ void TransportSocket::read_incoming_messages()
|
|||
message_size += sizeof(MessageHeader);
|
||||
if (message_size.has_overflow() || message_size.value() > m_unprocessed_bytes.size() - index)
|
||||
break;
|
||||
if (header.fd_count > m_unprocessed_fds.size())
|
||||
if (header.fd_count > m_unprocessed_attachments.size())
|
||||
break;
|
||||
auto message = make<Message>();
|
||||
received_fd_count += header.fd_count;
|
||||
|
|
@ -407,7 +406,7 @@ void TransportSocket::read_incoming_messages()
|
|||
break;
|
||||
}
|
||||
for (size_t i = 0; i < header.fd_count; ++i)
|
||||
message->fds.enqueue(m_unprocessed_fds.dequeue());
|
||||
message->attachments.enqueue(m_unprocessed_attachments.dequeue());
|
||||
if (message->bytes.try_append(m_unprocessed_bytes.data() + index + sizeof(MessageHeader), header.payload_size).is_error()) {
|
||||
dbgln("TransportSocket: Failed to allocate message buffer for payload_size {}", header.payload_size);
|
||||
m_peer_eof = true;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@
|
|||
#include <AK/MemoryStream.h>
|
||||
#include <AK/Queue.h>
|
||||
#include <LibCore/Socket.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/AutoCloseFileDescriptor.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibThreading/ConditionVariable.h>
|
||||
#include <LibThreading/Forward.h>
|
||||
|
||||
|
|
@ -57,7 +58,7 @@ public:
|
|||
|
||||
void wait_until_readable();
|
||||
|
||||
void post_message(Vector<u8> const&, Vector<NonnullRefPtr<AutoCloseFileDescriptor>> const&);
|
||||
void post_message(Vector<u8> const&, Vector<Attachment>& attachments);
|
||||
|
||||
enum class ShouldShutdown {
|
||||
No,
|
||||
|
|
@ -65,7 +66,7 @@ public:
|
|||
};
|
||||
struct Message {
|
||||
Vector<u8> bytes;
|
||||
Queue<File> fds;
|
||||
Queue<Attachment> attachments;
|
||||
};
|
||||
ShouldShutdown read_as_many_messages_as_possible_without_blocking(Function<void(Message&&)>&&);
|
||||
|
||||
|
|
@ -104,7 +105,7 @@ private:
|
|||
Atomic<IOThreadState> m_io_thread_state { IOThreadState::Running };
|
||||
Atomic<bool> m_peer_eof { false };
|
||||
ByteBuffer m_unprocessed_bytes;
|
||||
Queue<File> m_unprocessed_fds;
|
||||
Queue<Attachment> m_unprocessed_attachments;
|
||||
Threading::Mutex m_incoming_mutex;
|
||||
Threading::ConditionVariable m_incoming_cv { m_incoming_mutex };
|
||||
Vector<NonnullOwnPtr<Message>> m_incoming_messages;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <AK/Queue.h>
|
||||
#include <LibCore/Socket.h>
|
||||
#include <LibIPC/File.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
|
||||
namespace IPC {
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ public:
|
|||
};
|
||||
struct Message {
|
||||
Vector<u8> bytes;
|
||||
Queue<File> fds; // always empty, present to avoid OS #ifdefs in Connection.cpp
|
||||
Queue<Attachment> attachments; // always empty, present to avoid OS #ifdefs in Connection.cpp
|
||||
};
|
||||
ShouldShutdown read_as_many_messages_as_possible_without_blocking(Function<void(Message&&)>&&);
|
||||
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ void MessagePort::read_from_transport()
|
|||
|
||||
auto schedule_shutdown = m_transport->read_as_many_messages_as_possible_without_blocking([this](auto&& raw_message) {
|
||||
FixedMemoryStream stream { raw_message.bytes.span(), FixedMemoryStream::Mode::ReadOnly };
|
||||
IPC::Decoder decoder { stream, raw_message.fds };
|
||||
IPC::Decoder decoder { stream, raw_message.attachments };
|
||||
|
||||
auto serialized_transfer_record = MUST(decoder.decode<SerializedTransferRecord>());
|
||||
|
||||
|
|
|
|||
|
|
@ -1305,19 +1305,17 @@ void TransferDataEncoder::extend(Vector<TransferDataEncoder> data_holders)
|
|||
|
||||
TransferDataDecoder::TransferDataDecoder(SerializationRecord const& record)
|
||||
: m_stream(record.span())
|
||||
, m_decoder(m_stream, m_files)
|
||||
, m_decoder(m_stream, m_attachments)
|
||||
{
|
||||
}
|
||||
|
||||
TransferDataDecoder::TransferDataDecoder(TransferDataEncoder&& data_holder)
|
||||
: m_buffer(data_holder.take_buffer())
|
||||
, m_stream(m_buffer.data().span())
|
||||
, m_decoder(m_stream, m_files)
|
||||
, m_decoder(m_stream, m_attachments)
|
||||
{
|
||||
// FIXME: The churn between IPC::File and IPC::AutoCloseFileDescriptor is pretty awkward, we should find a way to
|
||||
// consolidate the way we use these type.
|
||||
for (auto& auto_fd : m_buffer.take_fds())
|
||||
m_files.enqueue(IPC::File::adopt_fd(auto_fd->take_fd()));
|
||||
for (auto& attachment : m_buffer.take_attachments())
|
||||
m_attachments.enqueue(move(attachment));
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<ByteBuffer> TransferDataDecoder::decode_buffer(JS::Realm& realm)
|
||||
|
|
@ -1339,13 +1337,11 @@ namespace IPC {
|
|||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, Web::HTML::TransferDataEncoder const& data_holder)
|
||||
{
|
||||
// FIXME: The churn between IPC::File and IPC::AutoCloseFileDescriptor is pretty awkward, we should find a way to
|
||||
// consolidate the way we use these type.
|
||||
Vector<IPC::File> files;
|
||||
files.ensure_capacity(data_holder.buffer().fds().size());
|
||||
files.ensure_capacity(data_holder.buffer().attachments().size());
|
||||
|
||||
for (auto const& auto_fd : data_holder.buffer().fds()) {
|
||||
auto fd = const_cast<AutoCloseFileDescriptor&>(*auto_fd).take_fd();
|
||||
for (auto& attachment : data_holder.buffer().attachments()) {
|
||||
int fd = const_cast<Attachment&>(attachment).to_fd();
|
||||
files.unchecked_append(IPC::File::adopt_fd(fd));
|
||||
}
|
||||
|
||||
|
|
@ -1360,17 +1356,13 @@ ErrorOr<Web::HTML::TransferDataEncoder> decode(Decoder& decoder)
|
|||
auto data = TRY(decoder.decode<Web::HTML::SerializationRecord>());
|
||||
auto files = TRY(decoder.decode<Vector<IPC::File>>());
|
||||
|
||||
// FIXME: The churn between IPC::File and IPC::AutoCloseFileDescriptor is pretty awkward, we should find a way to
|
||||
// consolidate the way we use these type.
|
||||
MessageFileType auto_files;
|
||||
auto_files.ensure_capacity(files.size());
|
||||
Vector<Attachment> attachments;
|
||||
attachments.ensure_capacity(files.size());
|
||||
|
||||
for (auto& fd : files) {
|
||||
auto auto_fd = adopt_ref(*new AutoCloseFileDescriptor(fd.take_fd()));
|
||||
auto_files.unchecked_append(move(auto_fd));
|
||||
}
|
||||
for (auto& file : files)
|
||||
attachments.unchecked_append(Attachment::from_fd(file.take_fd()));
|
||||
|
||||
IPC::MessageBuffer buffer { move(data), move(auto_files) };
|
||||
IPC::MessageBuffer buffer { move(data), move(attachments) };
|
||||
return Web::HTML::TransferDataEncoder { move(buffer) };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ private:
|
|||
IPC::MessageBuffer m_buffer;
|
||||
|
||||
FixedMemoryStream m_stream;
|
||||
Queue<IPC::File> m_files;
|
||||
Queue<IPC::Attachment> m_attachments;
|
||||
|
||||
IPC::Decoder m_decoder;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -405,9 +405,9 @@ public:)~~~");
|
|||
static i32 static_message_id() { return (int)MessageID::@message.pascal_name@; }
|
||||
virtual const char* message_name() const override { return "@endpoint.name@::@message.pascal_name@"; }
|
||||
|
||||
static ErrorOr<NonnullOwnPtr<@message.pascal_name@>> decode(Stream& stream, Queue<IPC::File>& files)
|
||||
static ErrorOr<NonnullOwnPtr<@message.pascal_name@>> decode(Stream& stream, Queue<IPC::Attachment>& attachments)
|
||||
{
|
||||
IPC::Decoder decoder { stream, files };)~~~");
|
||||
IPC::Decoder decoder { stream, attachments };)~~~");
|
||||
|
||||
for (auto const& parameter : parameters) {
|
||||
auto parameter_generator = message_generator.fork();
|
||||
|
|
@ -729,7 +729,7 @@ public:
|
|||
|
||||
static u32 static_magic() { return @endpoint.magic@; }
|
||||
|
||||
static ErrorOr<NonnullOwnPtr<IPC::Message>> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Queue<IPC::File>& files)
|
||||
static ErrorOr<NonnullOwnPtr<IPC::Message>> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Queue<IPC::Attachment>& attachments)
|
||||
{
|
||||
FixedMemoryStream stream { buffer };
|
||||
auto message_endpoint_magic = TRY(stream.read_value<u32>());)~~~");
|
||||
|
|
@ -758,7 +758,7 @@ public:
|
|||
|
||||
message_generator.append(R"~~~(
|
||||
case (int)Messages::@endpoint.name@::MessageID::@message.pascal_name@:
|
||||
return TRY(Messages::@endpoint.name@::@message.pascal_name@::decode(stream, files));)~~~");
|
||||
return TRY(Messages::@endpoint.name@::@message.pascal_name@::decode(stream, attachments));)~~~");
|
||||
};
|
||||
|
||||
do_decode_message(message.name);
|
||||
|
|
@ -911,6 +911,7 @@ void build(StringBuilder& builder, Vector<Endpoint> const& endpoints)
|
|||
#include <AK/Platform.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibIPC/Attachment.h>
|
||||
#include <LibIPC/Connection.h>
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
|
|
|
|||
Loading…
Reference in a new issue