From ece1b7422fae7ebf82397c71ac32c288db4e099e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 5 Oct 2022 13:54:09 +0200 Subject: LibIPC: Allow giving Connection a separate socket for FD passing Our IPC protocol currently relies on the behavior of recvfd() and sendfd() on SerenityOS, which provide an out-of-band queue that can be accessed independently of the in-band data stream. To make LibIPC usable on other platforms, this patch adds a mechanism where IPC::Connection can be given a dedicated socket for FD passing. This gives us the same behavior as the syscalls on SerenityOS, without having to change the protocol implementation. --- Userland/Libraries/LibIPC/Connection.cpp | 14 +++++++++++++- Userland/Libraries/LibIPC/Connection.h | 9 +++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibIPC/Connection.cpp b/Userland/Libraries/LibIPC/Connection.cpp index 6c0451788f..3f922d808f 100644 --- a/Userland/Libraries/LibIPC/Connection.cpp +++ b/Userland/Libraries/LibIPC/Connection.cpp @@ -20,6 +20,18 @@ ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr socket) +{ + m_fd_passing_socket = move(socket); +} + +Core::Stream::LocalSocket& ConnectionBase::fd_passing_socket() +{ + if (m_fd_passing_socket) + return *m_fd_passing_socket; + return *m_socket; +} + ErrorOr ConnectionBase::post_message(Message const& message) { return post_message(message.encode()); @@ -38,7 +50,7 @@ ErrorOr ConnectionBase::post_message(MessageBuffer buffer) #ifdef __serenity__ for (auto& fd : buffer.fds) { - if (auto result = m_socket->send_fd(fd.value()); result.is_error()) { + if (auto result = fd_passing_socket().send_fd(fd.value()); result.is_error()) { shutdown_with_error(result.error()); return result; } diff --git a/Userland/Libraries/LibIPC/Connection.h b/Userland/Libraries/LibIPC/Connection.h index 60ea681f28..e2a41c0dc6 100644 --- a/Userland/Libraries/LibIPC/Connection.h +++ b/Userland/Libraries/LibIPC/Connection.h @@ -33,6 +33,8 @@ class ConnectionBase : public Core::Object { public: virtual ~ConnectionBase() override = default; + void set_fd_passing_socket(NonnullOwnPtr); + bool is_open() const { return m_socket->is_open(); } ErrorOr post_message(Message const&); @@ -43,6 +45,7 @@ protected: explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr, u32 local_endpoint_magic); Core::Stream::LocalSocket& socket() { return *m_socket; } + Core::Stream::LocalSocket& fd_passing_socket(); virtual void may_have_become_unresponsive() { } virtual void did_become_responsive() { } @@ -60,6 +63,8 @@ protected: IPC::Stub& m_local_stub; NonnullOwnPtr m_socket; + OwnPtr m_fd_passing_socket; + RefPtr m_responsiveness_timer; NonnullOwnPtrVector m_unprocessed_messages; @@ -123,9 +128,9 @@ protected: break; index += sizeof(message_size); auto remaining_bytes = ReadonlyBytes { bytes.data() + index, message_size }; - if (auto message = LocalEndpoint::decode_message(remaining_bytes, *m_socket)) { + if (auto message = LocalEndpoint::decode_message(remaining_bytes, fd_passing_socket())) { m_unprocessed_messages.append(message.release_nonnull()); - } else if (auto message = PeerEndpoint::decode_message(remaining_bytes, *m_socket)) { + } else if (auto message = PeerEndpoint::decode_message(remaining_bytes, fd_passing_socket())) { m_unprocessed_messages.append(message.release_nonnull()); } else { dbgln("Failed to parse a message"); -- cgit v1.2.3