From 7021d30288f66339b3cdca986333c058b0193e6b Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 14 Nov 2022 08:13:37 -0500 Subject: [PATCH] Ladybird: Foward the WebContent passing socket FD by command line Rather than needing to set another environment variable for WebDriver's passing socket, let's forward these FDs by command line. This also moves the creation of the WebContent connection to a helper function so that the WebDriver connection can re-use it. --- Ladybird/WebContent/main.cpp | 60 ++++++++++++++++++++++-------------- Ladybird/WebContentView.cpp | 16 +++++++--- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/Ladybird/WebContent/main.cpp b/Ladybird/WebContent/main.cpp index 2623693cfa..a98656903b 100644 --- a/Ladybird/WebContent/main.cpp +++ b/Ladybird/WebContent/main.cpp @@ -13,11 +13,13 @@ #include "../Utilities.h" #include "../WebSocketClientManagerLadybird.h" #include +#include #include #include #include #include -#include +#include +#include #include #include #include @@ -32,6 +34,34 @@ static ErrorOr load_content_filters(); extern String s_serenity_resource_root; +struct DeferredInvokerQt final : IPC::DeferredInvoker { + virtual ~DeferredInvokerQt() = default; + virtual void schedule(Function callback) override + { + QTimer::singleShot(0, move(callback)); + } +}; + +template +static ErrorOr> create_connection_from_passed_socket(int passing_socket_fd, StringView socket_name, QSocketNotifier& notifier, Args&&... args) +{ + auto socket = TRY(Core::take_over_socket_from_system_server(socket_name)); + auto client = TRY(ConnectionType::try_create(move(socket), std::forward(args)...)); + + VERIFY(passing_socket_fd >= 0); + client->set_fd_passing_socket(TRY(Core::Stream::LocalSocket::adopt_fd(passing_socket_fd))); + + notifier.setSocket(client->socket().fd().value()); + notifier.setEnabled(true); + + QObject::connect(¬ifier, &QSocketNotifier::activated, [client]() mutable { + client->socket().notifier()->on_ready_to_read(); + }); + + client->set_deferred_invoker(make()); + return client; +} + ErrorOr serenity_main(Main::Arguments arguments) { // NOTE: This is only used for the Core::Socket inside the IPC connection. @@ -58,30 +88,14 @@ ErrorOr serenity_main(Main::Arguments arguments) if (maybe_content_filter_error.is_error()) dbgln("Failed to load content filters: {}", maybe_content_filter_error.error()); - auto client = TRY(IPC::take_over_accepted_client_from_system_server()); + int webcontent_fd_passing_socket { -1 }; - auto* fd_passing_socket_spec = getenv("FD_PASSING_SOCKET"); - VERIFY(fd_passing_socket_spec); - auto fd_passing_socket_spec_string = String(fd_passing_socket_spec); - auto maybe_fd_passing_socket = fd_passing_socket_spec_string.to_int(); - VERIFY(maybe_fd_passing_socket.has_value()); + Core::ArgsParser args_parser; + args_parser.add_option(webcontent_fd_passing_socket, "File descriptor of the passing socket for the WebContent connection", "webcontent-fd-passing-socket", 'c', "webcontent_fd_passing_socket"); + args_parser.parse(arguments); - client->set_fd_passing_socket(TRY(Core::Stream::LocalSocket::adopt_fd(maybe_fd_passing_socket.value()))); - - QSocketNotifier notifier(client->socket().fd().value(), QSocketNotifier::Type::Read); - QObject::connect(¬ifier, &QSocketNotifier::activated, [&] { - client->socket().notifier()->on_ready_to_read(); - }); - - struct DeferredInvokerQt final : IPC::DeferredInvoker { - virtual ~DeferredInvokerQt() = default; - virtual void schedule(Function callback) override - { - QTimer::singleShot(0, move(callback)); - } - }; - - client->set_deferred_invoker(make()); + QSocketNotifier webcontent_notifier(QSocketNotifier::Type::Read); + auto webcontent_client = TRY(create_connection_from_passed_socket(webcontent_fd_passing_socket, "WebContent"sv, webcontent_notifier)); return app.exec(); } diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index 9902037787..2c2dfca039 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -589,14 +589,20 @@ void WebContentView::create_client() auto takeover_string = String::formatted("WebContent:{}", wc_fd); MUST(Core::System::setenv("SOCKET_TAKEOVER"sv, takeover_string, true)); - auto fd_passing_socket_string = String::formatted("{}", wc_fd_passing_fd); - MUST(Core::System::setenv("FD_PASSING_SOCKET"sv, fd_passing_socket_string, true)); + auto fd_passing_socket_string = String::number(wc_fd_passing_fd); - auto rc = execlp("./WebContent/WebContent", "WebContent", nullptr); + char const* argv[] = { + "WebContent", + "--webcontent-fd-passing-socket", + fd_passing_socket_string.characters(), + nullptr, + }; + + auto rc = execvp("./WebContent/WebContent", const_cast(argv)); if (rc < 0) - rc = execlp((QCoreApplication::applicationDirPath() + "/WebContent").toStdString().c_str(), "WebContent", nullptr); + rc = execvp((QCoreApplication::applicationDirPath() + "/WebContent").toStdString().c_str(), const_cast(argv)); if (rc < 0) - perror("execlp"); + perror("execvp"); VERIFY_NOT_REACHED(); }