LibIPC+LibWeb: Preserve raw TransferDataEncoder attachments

Encode transfer-data attachments as raw IPC attachments instead of first
rewrapping them as IPC::File values.

This is preparatory refactoring for the upcoming Mach-port transport
introduction on macOS, where attachments should remain transport-native
rather than being normalized through file descriptors.
This commit is contained in:
Aliaksandr Kalenik 2026-03-20 23:31:05 +01:00 committed by Alexander Kalenik
parent 194f17928f
commit 03f142f54d
3 changed files with 18 additions and 14 deletions

View file

@ -37,6 +37,12 @@ Attachment Attachment::from_fd(int fd)
return attachment;
}
ErrorOr<Attachment> Attachment::clone() const
{
VERIFY(m_fd != -1);
return from_fd(TRY(Core::System::dup(m_fd)));
}
int Attachment::to_fd()
{
return exchange(m_fd, -1);

View file

@ -6,6 +6,7 @@
#pragma once
#include <AK/Error.h>
#include <AK/Noncopyable.h>
namespace IPC {
@ -20,6 +21,7 @@ public:
~Attachment();
static Attachment from_fd(int fd);
ErrorOr<Attachment> clone() const;
int to_fd();
private:

View file

@ -1337,16 +1337,13 @@ namespace IPC {
template<>
ErrorOr<void> encode(Encoder& encoder, Web::HTML::TransferDataEncoder const& data_holder)
{
Vector<IPC::File> files;
files.ensure_capacity(data_holder.buffer().attachments().size());
for (auto& attachment : data_holder.buffer().attachments()) {
int fd = const_cast<Attachment&>(attachment).to_fd();
files.unchecked_append(IPC::File::adopt_fd(fd));
}
TRY(encoder.encode(data_holder.buffer().data()));
TRY(encoder.encode(files));
auto const& attachments = data_holder.buffer().attachments();
TRY(encoder.encode(static_cast<u32>(attachments.size())));
for (auto const& attachment : attachments)
TRY(encoder.append_attachment(TRY(attachment.clone())));
return {};
}
@ -1354,13 +1351,12 @@ template<>
ErrorOr<Web::HTML::TransferDataEncoder> decode(Decoder& decoder)
{
auto data = TRY(decoder.decode<Web::HTML::SerializationRecord>());
auto files = TRY(decoder.decode<Vector<IPC::File>>());
auto attachment_count = TRY(decoder.decode<u32>());
Vector<Attachment> attachments;
attachments.ensure_capacity(files.size());
for (auto& file : files)
attachments.unchecked_append(Attachment::from_fd(file.take_fd()));
TRY(attachments.try_ensure_capacity(attachment_count));
for (u32 i = 0; i < attachment_count; ++i)
attachments.unchecked_append(TRY(decoder.attachments().try_dequeue()));
IPC::MessageBuffer buffer { move(data), move(attachments) };
return Web::HTML::TransferDataEncoder { move(buffer) };