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(); }