mirror of
https://github.com/RGBCube/serenity
synced 2025-05-18 09:05:07 +00:00
LibCore+LibIPC+Everywhere: Return Stream::LocalSocket from LocalServer
This change unfortunately cannot be atomically made without a single commit changing everything. Most of the important changes are in LibIPC/Connection.cpp, LibIPC/ServerConnection.cpp and LibCore/LocalServer.cpp. The notable changes are: - IPCCompiler now generates the decode and decode_message functions such that they take a Core::Stream::LocalSocket instead of the socket fd. - IPC::Decoder now uses the receive_fd method of LocalSocket instead of doing system calls directly on the fd. - IPC::ConnectionBase and related classes now use the Stream API functions. - IPC::ServerConnection no longer constructs the socket itself; instead, a convenience macro, IPC_CLIENT_CONNECTION, is used in place of C_OBJECT and will generate a static try_create factory function for the ServerConnection subclass. The subclass is now responsible for passing the socket constructed in this function to its ServerConnection base; the socket is passed as the first argument to the constructor (as a NonnullOwnPtr<Core::Stream::LocalServer>) before any other arguments. - The functionality regarding taking over sockets from SystemServer has been moved to LibIPC/SystemServerTakeover.cpp. The Core::LocalSocket implementation of this functionality hasn't been deleted due to my intention of removing this class in the near future and to reduce noise on this (already quite noisy) PR.
This commit is contained in:
parent
4cad0dd74c
commit
2e1bbcb0fa
94 changed files with 378 additions and 252 deletions
|
@ -368,9 +368,9 @@ public:
|
||||||
static i32 static_message_id() { return (int)MessageID::@message.pascal_name@; }
|
static i32 static_message_id() { return (int)MessageID::@message.pascal_name@; }
|
||||||
virtual const char* message_name() const override { return "@endpoint.name@::@message.pascal_name@"; }
|
virtual const char* message_name() const override { return "@endpoint.name@::@message.pascal_name@"; }
|
||||||
|
|
||||||
static OwnPtr<@message.pascal_name@> decode(InputMemoryStream& stream, [[maybe_unused]] int sockfd)
|
static OwnPtr<@message.pascal_name@> decode(InputMemoryStream& stream, Core::Stream::LocalSocket& socket)
|
||||||
{
|
{
|
||||||
IPC::Decoder decoder { stream, sockfd };
|
IPC::Decoder decoder { stream, socket };
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
for (auto& parameter : parameters) {
|
for (auto& parameter : parameters) {
|
||||||
|
@ -632,7 +632,7 @@ public:
|
||||||
|
|
||||||
static u32 static_magic() { return @endpoint.magic@; }
|
static u32 static_magic() { return @endpoint.magic@; }
|
||||||
|
|
||||||
static OwnPtr<IPC::Message> decode_message(ReadonlyBytes buffer, [[maybe_unused]] int sockfd)
|
static OwnPtr<IPC::Message> decode_message(ReadonlyBytes buffer, [[maybe_unused]] Core::Stream::LocalSocket& socket)
|
||||||
{
|
{
|
||||||
InputMemoryStream stream { buffer };
|
InputMemoryStream stream { buffer };
|
||||||
u32 message_endpoint_magic = 0;
|
u32 message_endpoint_magic = 0;
|
||||||
|
@ -685,7 +685,7 @@ public:
|
||||||
|
|
||||||
message_generator.append(R"~~~(
|
message_generator.append(R"~~~(
|
||||||
case (int)Messages::@endpoint.name@::MessageID::@message.pascal_name@:
|
case (int)Messages::@endpoint.name@::MessageID::@message.pascal_name@:
|
||||||
message = Messages::@endpoint.name@::@message.pascal_name@::decode(stream, sockfd);
|
message = Messages::@endpoint.name@::@message.pascal_name@::decode(stream, socket);
|
||||||
break;
|
break;
|
||||||
)~~~");
|
)~~~");
|
||||||
};
|
};
|
||||||
|
|
|
@ -300,8 +300,8 @@ TEST_CASE(local_socket_read)
|
||||||
auto local_server = Core::LocalServer::construct();
|
auto local_server = Core::LocalServer::construct();
|
||||||
EXPECT(local_server->listen("/tmp/test-socket"));
|
EXPECT(local_server->listen("/tmp/test-socket"));
|
||||||
|
|
||||||
local_server->on_accept = [&](NonnullRefPtr<Core::LocalSocket> server_socket) {
|
local_server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> server_socket) {
|
||||||
EXPECT(server_socket->write(sent_data));
|
EXPECT(!server_socket->write(sent_data.bytes()).is_error());
|
||||||
|
|
||||||
event_loop.quit(0);
|
event_loop.quit(0);
|
||||||
event_loop.pump();
|
event_loop.pump();
|
||||||
|
@ -346,14 +346,17 @@ TEST_CASE(local_socket_write)
|
||||||
auto local_server = Core::LocalServer::construct();
|
auto local_server = Core::LocalServer::construct();
|
||||||
EXPECT(local_server->listen("/tmp/test-socket"));
|
EXPECT(local_server->listen("/tmp/test-socket"));
|
||||||
|
|
||||||
local_server->on_accept = [&](NonnullRefPtr<Core::LocalSocket> server_socket) {
|
local_server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> server_socket) {
|
||||||
// NOTE: For some reason LocalServer gives us a nonblocking socket..?
|
// NOTE: For some reason LocalServer gives us a nonblocking socket..?
|
||||||
server_socket->set_blocking(true);
|
MUST(server_socket->set_blocking(true));
|
||||||
|
|
||||||
auto receive_buffer = server_socket->read_all();
|
auto pending_bytes = MUST(server_socket->pending_bytes());
|
||||||
EXPECT(!server_socket->error());
|
auto receive_buffer = ByteBuffer::create_uninitialized(pending_bytes).release_value();
|
||||||
|
auto maybe_nread = server_socket->read(receive_buffer);
|
||||||
|
EXPECT(!maybe_nread.is_error());
|
||||||
|
EXPECT(maybe_nread.value() == sent_data.length());
|
||||||
|
|
||||||
StringView received_data { receive_buffer.bytes() };
|
StringView received_data { receive_buffer.data(), maybe_nread.value() };
|
||||||
EXPECT_EQ(sent_data, received_data);
|
EXPECT_EQ(sent_data, received_data);
|
||||||
|
|
||||||
event_loop.quit(0);
|
event_loop.quit(0);
|
||||||
|
|
|
@ -41,14 +41,15 @@ public:
|
||||||
{ 0, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/audio-volume-zero.png")) },
|
{ 0, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/audio-volume-zero.png")) },
|
||||||
{ 0, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/audio-volume-muted.png")) }
|
{ 0, TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/audio-volume-muted.png")) }
|
||||||
};
|
};
|
||||||
NonnullRefPtr<AudioWidget> audio_widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AudioWidget(move(volume_level_bitmaps))));
|
auto audio_client = TRY(Audio::ClientConnection::try_create());
|
||||||
|
NonnullRefPtr<AudioWidget> audio_widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AudioWidget(move(audio_client), move(volume_level_bitmaps))));
|
||||||
TRY(audio_widget->try_initialize_graphical_elements());
|
TRY(audio_widget->try_initialize_graphical_elements());
|
||||||
return audio_widget;
|
return audio_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioWidget(Vector<VolumeBitmapPair, 5> volume_level_bitmaps)
|
AudioWidget(NonnullRefPtr<Audio::ClientConnection> audio_client, Vector<VolumeBitmapPair, 5> volume_level_bitmaps)
|
||||||
: m_audio_client(Audio::ClientConnection::construct())
|
: m_audio_client(move(audio_client))
|
||||||
, m_volume_level_bitmaps(move(volume_level_bitmaps))
|
, m_volume_level_bitmaps(move(volume_level_bitmaps))
|
||||||
, m_show_percent(Config::read_bool("AudioApplet", "Applet", "ShowPercent", false))
|
, m_show_percent(Config::read_bool("AudioApplet", "Applet", "ShowPercent", false))
|
||||||
{
|
{
|
||||||
|
|
|
@ -169,7 +169,7 @@ void ViewWidget::load_from_file(const String& path)
|
||||||
auto& mapped_file = *file_or_error.value();
|
auto& mapped_file = *file_or_error.value();
|
||||||
|
|
||||||
// Spawn a new ImageDecoder service process and connect to it.
|
// Spawn a new ImageDecoder service process and connect to it.
|
||||||
auto client = ImageDecoderClient::Client::construct();
|
auto client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
|
|
||||||
auto decoded_image_or_error = client->decode_image(mapped_file.bytes());
|
auto decoded_image_or_error = client->decode_image(mapped_file.bytes());
|
||||||
if (!decoded_image_or_error.has_value()) {
|
if (!decoded_image_or_error.has_value()) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ AudioPlayerLoop::AudioPlayerLoop(TrackManager& track_manager, bool& need_to_writ
|
||||||
, m_need_to_write_wav(need_to_write_wav)
|
, m_need_to_write_wav(need_to_write_wav)
|
||||||
, m_wav_writer(wav_writer)
|
, m_wav_writer(wav_writer)
|
||||||
{
|
{
|
||||||
m_audio_client = Audio::ClientConnection::construct();
|
m_audio_client = Audio::ClientConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
m_audio_client->on_finish_playing_buffer = [this](int buffer_id) {
|
m_audio_client->on_finish_playing_buffer = [this](int buffer_id) {
|
||||||
(void)buffer_id;
|
(void)buffer_id;
|
||||||
enqueue_audio();
|
enqueue_audio();
|
||||||
|
|
|
@ -56,7 +56,7 @@ void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect) con
|
||||||
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Image::try_decode_bitmap(ReadonlyBytes bitmap_data)
|
ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Image::try_decode_bitmap(ReadonlyBytes bitmap_data)
|
||||||
{
|
{
|
||||||
// Spawn a new ImageDecoder service process and connect to it.
|
// Spawn a new ImageDecoder service process and connect to it.
|
||||||
auto client = ImageDecoderClient::Client::construct();
|
auto client = TRY(ImageDecoderClient::Client::try_create());
|
||||||
|
|
||||||
// FIXME: Find a way to avoid the memory copying here.
|
// FIXME: Find a way to avoid the memory copying here.
|
||||||
auto maybe_decoded_image = client->decode_image(bitmap_data);
|
auto maybe_decoded_image = client->decode_image(bitmap_data);
|
||||||
|
|
|
@ -31,8 +31,8 @@ class ServerConnection
|
||||||
friend class ServerConnectionWrapper;
|
friend class ServerConnectionWrapper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ServerConnection(StringView socket, const String& project_path)
|
ServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, const String& project_path)
|
||||||
: IPC::ServerConnection<LanguageClientEndpoint, LanguageServerEndpoint>(*this, socket)
|
: IPC::ServerConnection<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
m_project_path = project_path;
|
m_project_path = project_path;
|
||||||
async_greet(m_project_path);
|
async_greet(m_project_path);
|
||||||
|
@ -159,7 +159,7 @@ ServerConnectionWrapper& ServerConnectionWrapper::get_or_create(const String& pr
|
||||||
if (wrapper)
|
if (wrapper)
|
||||||
return *wrapper;
|
return *wrapper;
|
||||||
|
|
||||||
auto connection_wrapper_ptr = make<ServerConnectionWrapper>(LanguageServerType::language_name(), [project_path]() { return LanguageServerType::construct(project_path); });
|
auto connection_wrapper_ptr = make<ServerConnectionWrapper>(LanguageServerType::language_name(), [project_path]() { return LanguageServerType::try_create(project_path).release_value_but_fixme_should_propagate_errors(); });
|
||||||
auto& connection_wrapper = *connection_wrapper_ptr;
|
auto& connection_wrapper = *connection_wrapper_ptr;
|
||||||
ServerConnectionInstances::set_instance_for_language(LanguageServerType::language_name(), move(connection_wrapper_ptr));
|
ServerConnectionInstances::set_instance_for_language(LanguageServerType::language_name(), move(connection_wrapper_ptr));
|
||||||
return connection_wrapper;
|
return connection_wrapper;
|
||||||
|
|
|
@ -12,19 +12,19 @@
|
||||||
#include <DevTools/HackStudio/LanguageServers/LanguageServerEndpoint.h>
|
#include <DevTools/HackStudio/LanguageServers/LanguageServerEndpoint.h>
|
||||||
#include <LibIPC/ServerConnection.h>
|
#include <LibIPC/ServerConnection.h>
|
||||||
|
|
||||||
#define LANGUAGE_CLIENT(language_name_, socket_name) \
|
#define LANGUAGE_CLIENT(language_name_, socket_name) \
|
||||||
namespace language_name_ { \
|
namespace language_name_ { \
|
||||||
class ServerConnection final : public HackStudio::ServerConnection { \
|
class ServerConnection final : public HackStudio::ServerConnection { \
|
||||||
C_OBJECT(ServerConnection) \
|
IPC_CLIENT_CONNECTION(ServerConnection, "/tmp/portal/language" #socket_name) \
|
||||||
public: \
|
public: \
|
||||||
static const char* language_name() { return #language_name_; } \
|
static const char* language_name() { return #language_name_; } \
|
||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
ServerConnection(const String& project_path) \
|
ServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, const String& project_path) \
|
||||||
: HackStudio::ServerConnection("/tmp/portal/language/" #socket_name, project_path) \
|
: HackStudio::ServerConnection(move(socket), project_path) \
|
||||||
{ \
|
{ \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LanguageClients {
|
namespace LanguageClients {
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace LanguageServers {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket), 1)
|
: IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket), 1)
|
||||||
{
|
{
|
||||||
s_connections.set(1, *this);
|
s_connections.set(1, *this);
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace LanguageServers {
|
||||||
|
|
||||||
class ClientConnection : public IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint> {
|
class ClientConnection : public IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint> {
|
||||||
public:
|
public:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
~ClientConnection() override;
|
~ClientConnection() override;
|
||||||
|
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ClientConnection final : public LanguageServers::ClientConnection {
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: LanguageServers::ClientConnection(move(socket))
|
: LanguageServers::ClientConnection(move(socket))
|
||||||
{
|
{
|
||||||
m_autocomplete_engine = make<CppComprehensionEngine>(m_filedb);
|
m_autocomplete_engine = make<CppComprehensionEngine>(m_filedb);
|
||||||
|
|
|
@ -16,7 +16,7 @@ class ClientConnection final : public LanguageServers::ClientConnection {
|
||||||
C_OBJECT(ClientConnection);
|
C_OBJECT(ClientConnection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: LanguageServers::ClientConnection(move(socket))
|
: LanguageServers::ClientConnection(move(socket))
|
||||||
{
|
{
|
||||||
m_autocomplete_engine = make<ShellComprehensionEngine>(m_filedb);
|
m_autocomplete_engine = make<ShellComprehensionEngine>(m_filedb);
|
||||||
|
|
|
@ -15,14 +15,14 @@ namespace Inspector {
|
||||||
class InspectorServerClient final
|
class InspectorServerClient final
|
||||||
: public IPC::ServerConnection<InspectorClientEndpoint, InspectorServerEndpoint>
|
: public IPC::ServerConnection<InspectorClientEndpoint, InspectorServerEndpoint>
|
||||||
, public InspectorClientEndpoint {
|
, public InspectorClientEndpoint {
|
||||||
C_OBJECT(InspectorServerClient);
|
IPC_CLIENT_CONNECTION(InspectorServerClient, "/tmp/portal/inspector")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~InspectorServerClient() override = default;
|
virtual ~InspectorServerClient() override = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InspectorServerClient()
|
InspectorServerClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<InspectorClientEndpoint, InspectorServerEndpoint>(*this, "/tmp/portal/inspector")
|
: IPC::ServerConnection<InspectorClientEndpoint, InspectorServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ RemoteProcess::RemoteProcess(pid_t pid)
|
||||||
, m_object_graph_model(RemoteObjectGraphModel::create(*this))
|
, m_object_graph_model(RemoteObjectGraphModel::create(*this))
|
||||||
{
|
{
|
||||||
s_the = this;
|
s_the = this;
|
||||||
m_client = InspectorServerClient::construct();
|
m_client = InspectorServerClient::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteProcess::handle_identify_response(const JsonObject& response)
|
void RemoteProcess::handle_identify_response(const JsonObject& response)
|
||||||
|
|
|
@ -14,8 +14,8 @@ namespace Audio {
|
||||||
// Real-time audio may be improved with a lower value.
|
// Real-time audio may be improved with a lower value.
|
||||||
static timespec g_enqueue_wait_time { 0, 10'000'000 };
|
static timespec g_enqueue_wait_time { 0, 10'000'000 };
|
||||||
|
|
||||||
ClientConnection::ClientConnection()
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>(*this, "/tmp/portal/audio")
|
: IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ class Buffer;
|
||||||
class ClientConnection final
|
class ClientConnection final
|
||||||
: public IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>
|
: public IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>
|
||||||
, public AudioClientEndpoint {
|
, public AudioClientEndpoint {
|
||||||
C_OBJECT(ClientConnection)
|
IPC_CLIENT_CONNECTION(ClientConnection, "/tmp/portal/audio")
|
||||||
public:
|
public:
|
||||||
void enqueue(Buffer const&);
|
void enqueue(Buffer const&);
|
||||||
bool try_enqueue(Buffer const&);
|
bool try_enqueue(Buffer const&);
|
||||||
|
@ -29,7 +29,7 @@ public:
|
||||||
Function<void(double volume)> on_client_volume_change;
|
Function<void(double volume)> on_client_volume_change;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientConnection();
|
ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual void finished_playing_buffer(i32) override;
|
virtual void finished_playing_buffer(i32) override;
|
||||||
virtual void main_mix_muted_state_changed(bool) override;
|
virtual void main_mix_muted_state_changed(bool) override;
|
||||||
|
|
|
@ -15,7 +15,7 @@ Client& Client::the()
|
||||||
{
|
{
|
||||||
if (!s_the || !s_the->is_open()) {
|
if (!s_the || !s_the->is_open()) {
|
||||||
VERIFY(Core::EventLoop::has_been_instantiated());
|
VERIFY(Core::EventLoop::has_been_instantiated());
|
||||||
s_the = Client::construct();
|
s_the = Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
}
|
}
|
||||||
return *s_the;
|
return *s_the;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Config {
|
||||||
class Client final
|
class Client final
|
||||||
: public IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>
|
: public IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>
|
||||||
, public ConfigClientEndpoint {
|
, public ConfigClientEndpoint {
|
||||||
C_OBJECT(Client);
|
IPC_CLIENT_CONNECTION(Client, "/tmp/portal/config")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void pledge_domains(Vector<String> const&);
|
void pledge_domains(Vector<String> const&);
|
||||||
|
@ -39,8 +39,8 @@ public:
|
||||||
static Client& the();
|
static Client& the();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Client()
|
explicit Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, "/tmp/portal/config")
|
: IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <LibCore/LocalServer.h>
|
#include <LibCore/LocalServer.h>
|
||||||
#include <LibCore/LocalSocket.h>
|
#include <LibCore/LocalSocket.h>
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -80,8 +81,13 @@ void LocalServer::setup_notifier()
|
||||||
m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
|
m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
|
||||||
m_notifier->on_ready_to_read = [this] {
|
m_notifier->on_ready_to_read = [this] {
|
||||||
if (on_accept) {
|
if (on_accept) {
|
||||||
if (auto client_socket = accept())
|
auto maybe_client_socket = accept();
|
||||||
on_accept(client_socket.release_nonnull());
|
if (maybe_client_socket.is_error()) {
|
||||||
|
dbgln("LocalServer::on_ready_to_read: Error accepting a connection: {} (FIXME: should propagate!)", maybe_client_socket.error());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
on_accept(maybe_client_socket.release_value());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -134,7 +140,7 @@ bool LocalServer::listen(const String& address)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<LocalSocket> LocalServer::accept()
|
ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> LocalServer::accept()
|
||||||
{
|
{
|
||||||
VERIFY(m_listening);
|
VERIFY(m_listening);
|
||||||
sockaddr_un un;
|
sockaddr_un un;
|
||||||
|
@ -145,8 +151,7 @@ RefPtr<LocalSocket> LocalServer::accept()
|
||||||
int accepted_fd = ::accept(m_fd, (sockaddr*)&un, &un_size);
|
int accepted_fd = ::accept(m_fd, (sockaddr*)&un, &un_size);
|
||||||
#endif
|
#endif
|
||||||
if (accepted_fd < 0) {
|
if (accepted_fd < 0) {
|
||||||
perror("accept");
|
return Error::from_syscall("accept", -errno);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AK_OS_MACOS
|
#ifdef AK_OS_MACOS
|
||||||
|
@ -155,7 +160,7 @@ RefPtr<LocalSocket> LocalServer::accept()
|
||||||
(void)fcntl(accepted_fd, F_SETFD, FD_CLOEXEC);
|
(void)fcntl(accepted_fd, F_SETFD, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return LocalSocket::construct(accepted_fd);
|
return Stream::LocalSocket::adopt_fd(accepted_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
#include <LibCore/Object.h>
|
#include <LibCore/Object.h>
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
@ -20,9 +21,9 @@ public:
|
||||||
bool is_listening() const { return m_listening; }
|
bool is_listening() const { return m_listening; }
|
||||||
bool listen(const String& address);
|
bool listen(const String& address);
|
||||||
|
|
||||||
RefPtr<LocalSocket> accept();
|
ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> accept();
|
||||||
|
|
||||||
Function<void(NonnullRefPtr<Core::LocalSocket>)> on_accept;
|
Function<void(NonnullOwnPtr<Stream::LocalSocket>)> on_accept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit LocalServer(Object* parent = nullptr);
|
explicit LocalServer(Object* parent = nullptr);
|
||||||
|
|
|
@ -36,17 +36,17 @@ auto Launcher::Details::from_details_str(const String& details_str) -> NonnullRe
|
||||||
class LaunchServerConnection final
|
class LaunchServerConnection final
|
||||||
: public IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>
|
: public IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>
|
||||||
, public LaunchClientEndpoint {
|
, public LaunchClientEndpoint {
|
||||||
C_OBJECT(LaunchServerConnection)
|
IPC_CLIENT_CONNECTION(LaunchServerConnection, "/tmp/portal/launch")
|
||||||
private:
|
private:
|
||||||
LaunchServerConnection()
|
LaunchServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>(*this, "/tmp/portal/launch")
|
: IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static LaunchServerConnection& connection()
|
static LaunchServerConnection& connection()
|
||||||
{
|
{
|
||||||
static auto connection = LaunchServerConnection::construct();
|
static auto connection = LaunchServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ static RefPtr<Client> s_the = nullptr;
|
||||||
Client& Client::the()
|
Client& Client::the()
|
||||||
{
|
{
|
||||||
if (!s_the || !s_the->is_open())
|
if (!s_the || !s_the->is_open())
|
||||||
s_the = Client::construct();
|
s_the = Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
return *s_the;
|
return *s_the;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct Result {
|
||||||
class Client final
|
class Client final
|
||||||
: public IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>
|
: public IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>
|
||||||
, public FileSystemAccessClientEndpoint {
|
, public FileSystemAccessClientEndpoint {
|
||||||
C_OBJECT(Client)
|
IPC_CLIENT_CONNECTION(Client, "/tmp/portal/filesystemaccess")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Result request_file_read_only_approved(i32 parent_window_id, String const& path);
|
Result request_file_read_only_approved(i32 parent_window_id, String const& path);
|
||||||
|
@ -38,8 +38,8 @@ protected:
|
||||||
void die() override;
|
void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Client()
|
explicit Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, "/tmp/portal/filesystemaccess")
|
: IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ namespace GUI {
|
||||||
class ClipboardServerConnection final
|
class ClipboardServerConnection final
|
||||||
: public IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
: public IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
||||||
, public ClipboardClientEndpoint {
|
, public ClipboardClientEndpoint {
|
||||||
C_OBJECT(ClipboardServerConnection);
|
IPC_CLIENT_CONNECTION(ClipboardServerConnection, "/tmp/portal/clipboard")
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClipboardServerConnection()
|
ClipboardServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, "/tmp/portal/clipboard")
|
: IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static ClipboardServerConnection* s_connection;
|
static RefPtr<ClipboardServerConnection> s_connection;
|
||||||
|
|
||||||
static ClipboardServerConnection& connection()
|
static ClipboardServerConnection& connection()
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ static ClipboardServerConnection& connection()
|
||||||
|
|
||||||
void Clipboard::initialize(Badge<Application>)
|
void Clipboard::initialize(Badge<Application>)
|
||||||
{
|
{
|
||||||
s_connection = &ClipboardServerConnection::construct().leak_ref();
|
s_connection = ClipboardServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
Clipboard& Clipboard::the()
|
Clipboard& Clipboard::the()
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace GUI {
|
||||||
class NotificationServerConnection final
|
class NotificationServerConnection final
|
||||||
: public IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>
|
: public IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>
|
||||||
, public NotificationClientEndpoint {
|
, public NotificationClientEndpoint {
|
||||||
C_OBJECT(NotificationServerConnection)
|
IPC_CLIENT_CONNECTION(NotificationServerConnection, "/tmp/portal/notify")
|
||||||
|
|
||||||
friend class Notification;
|
friend class Notification;
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit NotificationServerConnection(Notification* notification)
|
explicit NotificationServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, Notification* notification)
|
||||||
: IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>(*this, "/tmp/portal/notify")
|
: IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>(*this, move(socket))
|
||||||
, m_notification(notification)
|
, m_notification(notification)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ void Notification::show()
|
||||||
{
|
{
|
||||||
VERIFY(!m_shown && !m_destroyed);
|
VERIFY(!m_shown && !m_destroyed);
|
||||||
auto icon = m_icon ? m_icon->to_shareable_bitmap() : Gfx::ShareableBitmap();
|
auto icon = m_icon ? m_icon->to_shareable_bitmap() : Gfx::ShareableBitmap();
|
||||||
m_connection = NotificationServerConnection::construct(this);
|
m_connection = NotificationServerConnection::try_create(this).release_value_but_fixme_should_propagate_errors();
|
||||||
m_connection->show_notification(m_text, m_title, icon);
|
m_connection->show_notification(m_text, m_title, icon);
|
||||||
m_shown = true;
|
m_shown = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@ namespace GUI {
|
||||||
|
|
||||||
WindowManagerServerConnection& WindowManagerServerConnection::the()
|
WindowManagerServerConnection& WindowManagerServerConnection::the()
|
||||||
{
|
{
|
||||||
static WindowManagerServerConnection* s_connection = nullptr;
|
static RefPtr<WindowManagerServerConnection> s_connection = nullptr;
|
||||||
if (!s_connection)
|
if (!s_connection)
|
||||||
s_connection = new WindowManagerServerConnection;
|
s_connection = WindowManagerServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
return *s_connection;
|
return *s_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,14 @@ namespace GUI {
|
||||||
class WindowManagerServerConnection final
|
class WindowManagerServerConnection final
|
||||||
: public IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>
|
: public IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>
|
||||||
, public WindowManagerClientEndpoint {
|
, public WindowManagerClientEndpoint {
|
||||||
C_OBJECT(WindowManagerServerConnection)
|
IPC_CLIENT_CONNECTION(WindowManagerServerConnection, "/tmp/portal/wm")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static WindowManagerServerConnection& the();
|
static WindowManagerServerConnection& the();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WindowManagerServerConnection()
|
WindowManagerServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, "/tmp/portal/wm")
|
: IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@ namespace GUI {
|
||||||
|
|
||||||
WindowServerConnection& WindowServerConnection::the()
|
WindowServerConnection& WindowServerConnection::the()
|
||||||
{
|
{
|
||||||
static WindowServerConnection* s_connection = nullptr;
|
static RefPtr<WindowServerConnection> s_connection = nullptr;
|
||||||
if (!s_connection)
|
if (!s_connection)
|
||||||
s_connection = new WindowServerConnection;
|
s_connection = WindowServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
return *s_connection;
|
return *s_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ static void set_system_theme_from_anonymous_buffer(Core::AnonymousBuffer buffer)
|
||||||
Application::the()->set_system_palette(buffer);
|
Application::the()->set_system_palette(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowServerConnection::WindowServerConnection()
|
WindowServerConnection::WindowServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>(*this, "/tmp/portal/window")
|
: IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
// NOTE: WindowServer automatically sends a "fast_greet" message to us when we connect.
|
// NOTE: WindowServer automatically sends a "fast_greet" message to us when we connect.
|
||||||
// All we have to do is wait for it to arrive. This avoids a round-trip during application startup.
|
// All we have to do is wait for it to arrive. This avoids a round-trip during application startup.
|
||||||
|
|
|
@ -16,13 +16,13 @@ namespace GUI {
|
||||||
class WindowServerConnection final
|
class WindowServerConnection final
|
||||||
: public IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>
|
: public IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>
|
||||||
, public WindowClientEndpoint {
|
, public WindowClientEndpoint {
|
||||||
C_OBJECT(WindowServerConnection)
|
IPC_CLIENT_CONNECTION(WindowServerConnection, "/tmp/portal/window")
|
||||||
public:
|
public:
|
||||||
static WindowServerConnection& the();
|
static WindowServerConnection& the();
|
||||||
i32 expose_client_id() { return m_client_id; }
|
i32 expose_client_id() { return m_client_id; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WindowServerConnection();
|
WindowServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual void fast_greet(Vector<Gfx::IntRect> const&, u32, u32, u32, Core::AnonymousBuffer const&, String const&, String const&, i32) override;
|
virtual void fast_greet(Vector<Gfx::IntRect> const&, u32, u32, u32, Core::AnonymousBuffer const&, String const&, String const&, i32) override;
|
||||||
virtual void paint(i32, Gfx::IntSize const&, Vector<Gfx::IntRect> const&) override;
|
virtual void paint(i32, Gfx::IntSize const&, Vector<Gfx::IntRect> const&) override;
|
||||||
|
|
|
@ -4,6 +4,7 @@ set(SOURCES
|
||||||
Encoder.cpp
|
Encoder.cpp
|
||||||
Message.cpp
|
Message.cpp
|
||||||
Stub.cpp
|
Stub.cpp
|
||||||
|
SystemServerTakeover.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
serenity_lib(LibIPC ipc)
|
serenity_lib(LibIPC ipc)
|
||||||
|
|
|
@ -24,12 +24,12 @@ public:
|
||||||
using ServerStub = typename ServerEndpoint::Stub;
|
using ServerStub = typename ServerEndpoint::Stub;
|
||||||
using IPCProxy = typename ClientEndpoint::template Proxy<ServerEndpoint>;
|
using IPCProxy = typename ClientEndpoint::template Proxy<ServerEndpoint>;
|
||||||
|
|
||||||
ClientConnection(ServerStub& stub, NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
ClientConnection(ServerStub& stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
|
||||||
: IPC::Connection<ServerEndpoint, ClientEndpoint>(stub, move(socket))
|
: IPC::Connection<ServerEndpoint, ClientEndpoint>(stub, move(socket))
|
||||||
, ClientEndpoint::template Proxy<ServerEndpoint>(*this, {})
|
, ClientEndpoint::template Proxy<ServerEndpoint>(*this, {})
|
||||||
, m_client_id(client_id)
|
, m_client_id(client_id)
|
||||||
{
|
{
|
||||||
VERIFY(this->socket().is_connected());
|
VERIFY(this->socket().is_open());
|
||||||
this->socket().on_ready_to_read = [this] {
|
this->socket().on_ready_to_read = [this] {
|
||||||
// FIXME: Do something about errors.
|
// FIXME: Do something about errors.
|
||||||
(void)this->drain_messages_from_peer();
|
(void)this->drain_messages_from_peer();
|
||||||
|
|
|
@ -11,10 +11,9 @@
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullRefPtr<Core::LocalSocket> socket, u32 local_endpoint_magic)
|
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, u32 local_endpoint_magic)
|
||||||
: m_local_stub(local_stub)
|
: m_local_stub(local_stub)
|
||||||
, m_socket(move(socket))
|
, m_socket(move(socket))
|
||||||
, m_notifier(Core::Notifier::construct(m_socket->fd(), Core::Notifier::Read, this))
|
|
||||||
, m_local_endpoint_magic(local_endpoint_magic)
|
, m_local_endpoint_magic(local_endpoint_magic)
|
||||||
{
|
{
|
||||||
m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); });
|
m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); });
|
||||||
|
@ -42,7 +41,7 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
||||||
|
|
||||||
#ifdef __serenity__
|
#ifdef __serenity__
|
||||||
for (auto& fd : buffer.fds) {
|
for (auto& fd : buffer.fds) {
|
||||||
if (auto result = Core::System::sendfd(m_socket->fd(), fd.value()); result.is_error()) {
|
if (auto result = m_socket->send_fd(fd.value()); result.is_error()) {
|
||||||
dbgln("{}", result.error());
|
dbgln("{}", result.error());
|
||||||
shutdown();
|
shutdown();
|
||||||
return result;
|
return result;
|
||||||
|
@ -53,23 +52,29 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
||||||
warnln("fd passing is not supported on this platform, sorry :(");
|
warnln("fd passing is not supported on this platform, sorry :(");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t total_nwritten = 0;
|
ReadonlyBytes bytes_to_write { buffer.data.span() };
|
||||||
while (total_nwritten < buffer.data.size()) {
|
while (!bytes_to_write.is_empty()) {
|
||||||
auto nwritten = write(m_socket->fd(), buffer.data.data() + total_nwritten, buffer.data.size() - total_nwritten);
|
auto maybe_nwritten = m_socket->write(bytes_to_write);
|
||||||
if (nwritten < 0) {
|
if (maybe_nwritten.is_error()) {
|
||||||
switch (errno) {
|
auto error = maybe_nwritten.release_error();
|
||||||
case EPIPE:
|
if (error.is_errno()) {
|
||||||
shutdown();
|
switch (error.code()) {
|
||||||
return Error::from_string_literal("IPC::Connection::post_message: Disconnected from peer"sv);
|
case EPIPE:
|
||||||
case EAGAIN:
|
shutdown();
|
||||||
shutdown();
|
return Error::from_string_literal("IPC::Connection::post_message: Disconnected from peer"sv);
|
||||||
return Error::from_string_literal("IPC::Connection::post_message: Peer buffer overflowed"sv);
|
case EAGAIN:
|
||||||
default:
|
shutdown();
|
||||||
shutdown();
|
return Error::from_string_literal("IPC::Connection::post_message: Peer buffer overflowed"sv);
|
||||||
return Error::from_syscall("IPC::Connection::post_message write"sv, -errno);
|
default:
|
||||||
|
shutdown();
|
||||||
|
return Error::from_syscall("IPC::Connection::post_message write"sv, -error.code());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
total_nwritten += nwritten;
|
|
||||||
|
bytes_to_write = bytes_to_write.slice(maybe_nwritten.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_responsiveness_timer->start();
|
m_responsiveness_timer->start();
|
||||||
|
@ -78,7 +83,6 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
||||||
|
|
||||||
void ConnectionBase::shutdown()
|
void ConnectionBase::shutdown()
|
||||||
{
|
{
|
||||||
m_notifier->close();
|
|
||||||
m_socket->close();
|
m_socket->close();
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
@ -99,21 +103,14 @@ void ConnectionBase::handle_messages()
|
||||||
|
|
||||||
void ConnectionBase::wait_for_socket_to_become_readable()
|
void ConnectionBase::wait_for_socket_to_become_readable()
|
||||||
{
|
{
|
||||||
fd_set read_fds;
|
auto maybe_did_become_readable = m_socket->can_read_without_blocking(-1);
|
||||||
FD_ZERO(&read_fds);
|
if (maybe_did_become_readable.is_error()) {
|
||||||
FD_SET(m_socket->fd(), &read_fds);
|
dbgln("ConnectionBase::wait_for_socket_to_become_readable: {}", maybe_did_become_readable.error());
|
||||||
for (;;) {
|
warnln("ConnectionBase::wait_for_socket_to_become_readable: {}", maybe_did_become_readable.error());
|
||||||
if (auto rc = select(m_socket->fd() + 1, &read_fds, nullptr, nullptr, nullptr); rc < 0) {
|
VERIFY_NOT_REACHED();
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
perror("wait_for_specific_endpoint_message: select");
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
} else {
|
|
||||||
VERIFY(rc > 0);
|
|
||||||
VERIFY(FD_ISSET(m_socket->fd(), &read_fds));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VERIFY(maybe_did_become_readable.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without_blocking()
|
ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without_blocking()
|
||||||
|
@ -125,15 +122,21 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
||||||
m_unprocessed_bytes.clear();
|
m_unprocessed_bytes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 buffer[4096];
|
||||||
while (m_socket->is_open()) {
|
while (m_socket->is_open()) {
|
||||||
u8 buffer[4096];
|
auto maybe_nread = m_socket->read_without_waiting({ buffer, 4096 });
|
||||||
ssize_t nread = recv(m_socket->fd(), buffer, sizeof(buffer), MSG_DONTWAIT);
|
if (maybe_nread.is_error()) {
|
||||||
if (nread < 0) {
|
auto error = maybe_nread.release_error();
|
||||||
if (errno == EAGAIN)
|
if (error.is_syscall() && error.code() == EAGAIN) {
|
||||||
break;
|
break;
|
||||||
perror("recv");
|
}
|
||||||
exit(1);
|
|
||||||
|
dbgln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
||||||
|
warnln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto nread = maybe_nread.release_value();
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
if (bytes.is_empty()) {
|
if (bytes.is_empty()) {
|
||||||
deferred_invoke([this] { shutdown(); });
|
deferred_invoke([this] { shutdown(); });
|
||||||
|
@ -141,6 +144,7 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.append(buffer, nread);
|
bytes.append(buffer, nread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include <AK/Try.h>
|
#include <AK/Try.h>
|
||||||
#include <LibCore/Event.h>
|
#include <LibCore/Event.h>
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
#include <LibCore/LocalSocket.h>
|
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
#include <LibCore/Timer.h>
|
#include <LibCore/Timer.h>
|
||||||
#include <LibIPC/Forward.h>
|
#include <LibIPC/Forward.h>
|
||||||
#include <LibIPC/Message.h>
|
#include <LibIPC/Message.h>
|
||||||
|
@ -39,9 +39,9 @@ public:
|
||||||
virtual void die() { }
|
virtual void die() { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConnectionBase(IPC::Stub&, NonnullRefPtr<Core::LocalSocket>, u32 local_endpoint_magic);
|
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::Stream::LocalSocket>, u32 local_endpoint_magic);
|
||||||
|
|
||||||
Core::LocalSocket& socket() { return *m_socket; }
|
Core::Stream::LocalSocket& socket() { return *m_socket; }
|
||||||
|
|
||||||
virtual void may_have_become_unresponsive() { }
|
virtual void may_have_become_unresponsive() { }
|
||||||
virtual void did_become_responsive() { }
|
virtual void did_become_responsive() { }
|
||||||
|
@ -57,10 +57,9 @@ protected:
|
||||||
|
|
||||||
IPC::Stub& m_local_stub;
|
IPC::Stub& m_local_stub;
|
||||||
|
|
||||||
NonnullRefPtr<Core::LocalSocket> m_socket;
|
NonnullOwnPtr<Core::Stream::LocalSocket> m_socket;
|
||||||
RefPtr<Core::Timer> m_responsiveness_timer;
|
RefPtr<Core::Timer> m_responsiveness_timer;
|
||||||
|
|
||||||
RefPtr<Core::Notifier> m_notifier;
|
|
||||||
NonnullOwnPtrVector<Message> m_unprocessed_messages;
|
NonnullOwnPtrVector<Message> m_unprocessed_messages;
|
||||||
ByteBuffer m_unprocessed_bytes;
|
ByteBuffer m_unprocessed_bytes;
|
||||||
|
|
||||||
|
@ -70,10 +69,10 @@ protected:
|
||||||
template<typename LocalEndpoint, typename PeerEndpoint>
|
template<typename LocalEndpoint, typename PeerEndpoint>
|
||||||
class Connection : public ConnectionBase {
|
class Connection : public ConnectionBase {
|
||||||
public:
|
public:
|
||||||
Connection(IPC::Stub& local_stub, NonnullRefPtr<Core::LocalSocket> socket)
|
Connection(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: ConnectionBase(local_stub, move(socket), LocalEndpoint::static_magic())
|
: ConnectionBase(local_stub, move(socket), LocalEndpoint::static_magic())
|
||||||
{
|
{
|
||||||
m_notifier->on_ready_to_read = [this] {
|
m_socket->on_ready_to_read = [this] {
|
||||||
NonnullRefPtr protect = *this;
|
NonnullRefPtr protect = *this;
|
||||||
// FIXME: Do something about errors.
|
// FIXME: Do something about errors.
|
||||||
(void)drain_messages_from_peer();
|
(void)drain_messages_from_peer();
|
||||||
|
@ -122,9 +121,9 @@ protected:
|
||||||
break;
|
break;
|
||||||
index += sizeof(message_size);
|
index += sizeof(message_size);
|
||||||
auto remaining_bytes = ReadonlyBytes { bytes.data() + index, message_size };
|
auto remaining_bytes = ReadonlyBytes { bytes.data() + index, message_size };
|
||||||
if (auto message = LocalEndpoint::decode_message(remaining_bytes, m_socket->fd())) {
|
if (auto message = LocalEndpoint::decode_message(remaining_bytes, *m_socket)) {
|
||||||
m_unprocessed_messages.append(message.release_nonnull());
|
m_unprocessed_messages.append(message.release_nonnull());
|
||||||
} else if (auto message = PeerEndpoint::decode_message(remaining_bytes, m_socket->fd())) {
|
} else if (auto message = PeerEndpoint::decode_message(remaining_bytes, *m_socket)) {
|
||||||
m_unprocessed_messages.append(message.release_nonnull());
|
m_unprocessed_messages.append(message.release_nonnull());
|
||||||
} else {
|
} else {
|
||||||
dbgln("Failed to parse a message");
|
dbgln("Failed to parse a message");
|
||||||
|
|
|
@ -162,14 +162,9 @@ ErrorOr<void> Decoder::decode(Dictionary& dictionary)
|
||||||
|
|
||||||
ErrorOr<void> Decoder::decode([[maybe_unused]] File& file)
|
ErrorOr<void> Decoder::decode([[maybe_unused]] File& file)
|
||||||
{
|
{
|
||||||
#ifdef __serenity__
|
int fd = TRY(m_socket.receive_fd(O_CLOEXEC));
|
||||||
int fd = TRY(Core::System::recvfd(m_sockfd, O_CLOEXEC));
|
|
||||||
file = File(fd, File::ConstructWithReceivedFileDescriptor);
|
file = File(fd, File::ConstructWithReceivedFileDescriptor);
|
||||||
return {};
|
return {};
|
||||||
#else
|
|
||||||
[[maybe_unused]] auto fd = m_sockfd;
|
|
||||||
return Error::from_string_literal("File descriptor passing not supported on this platform");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> decode(Decoder& decoder, Core::AnonymousBuffer& buffer)
|
ErrorOr<void> decode(Decoder& decoder, Core::AnonymousBuffer& buffer)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <AK/NumericLimits.h>
|
#include <AK/NumericLimits.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
#include <LibIPC/Forward.h>
|
#include <LibIPC/Forward.h>
|
||||||
#include <LibIPC/Message.h>
|
#include <LibIPC/Message.h>
|
||||||
|
|
||||||
|
@ -25,9 +26,9 @@ inline ErrorOr<void> decode(Decoder&, T&)
|
||||||
|
|
||||||
class Decoder {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
Decoder(InputMemoryStream& stream, int sockfd)
|
Decoder(InputMemoryStream& stream, Core::Stream::LocalSocket& socket)
|
||||||
: m_stream(stream)
|
: m_stream(stream)
|
||||||
, m_sockfd(sockfd)
|
, m_socket(socket)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InputMemoryStream& m_stream;
|
InputMemoryStream& m_stream;
|
||||||
int m_sockfd { -1 };
|
Core::Stream::LocalSocket& m_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,24 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
#include <LibIPC/Connection.h>
|
#include <LibIPC/Connection.h>
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
|
#define IPC_CLIENT_CONNECTION(klass, socket_path) \
|
||||||
|
C_OBJECT_ABSTRACT(klass) \
|
||||||
|
public: \
|
||||||
|
template<typename Klass = klass, class... Args> \
|
||||||
|
static ErrorOr<NonnullRefPtr<klass>> try_create(Args&&... args) \
|
||||||
|
{ \
|
||||||
|
auto socket = TRY(Core::Stream::LocalSocket::connect(socket_path)); \
|
||||||
|
/* We want to rate-limit our clients */ \
|
||||||
|
TRY(socket->set_blocking(true)); \
|
||||||
|
\
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) Klass(move(socket), forward<Args>(args)...)); \
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ClientEndpoint, typename ServerEndpoint>
|
template<typename ClientEndpoint, typename ServerEndpoint>
|
||||||
class ServerConnection : public IPC::Connection<ClientEndpoint, ServerEndpoint>
|
class ServerConnection : public IPC::Connection<ClientEndpoint, ServerEndpoint>
|
||||||
, public ClientEndpoint::Stub
|
, public ClientEndpoint::Stub
|
||||||
|
@ -18,19 +32,10 @@ public:
|
||||||
using ClientStub = typename ClientEndpoint::Stub;
|
using ClientStub = typename ClientEndpoint::Stub;
|
||||||
using IPCProxy = typename ServerEndpoint::template Proxy<ClientEndpoint>;
|
using IPCProxy = typename ServerEndpoint::template Proxy<ClientEndpoint>;
|
||||||
|
|
||||||
ServerConnection(ClientStub& local_endpoint, StringView address)
|
ServerConnection(ClientStub& local_endpoint, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, Core::LocalSocket::construct())
|
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, move(socket))
|
||||||
, ServerEndpoint::template Proxy<ClientEndpoint>(*this, {})
|
, ServerEndpoint::template Proxy<ClientEndpoint>(*this, {})
|
||||||
{
|
{
|
||||||
// We want to rate-limit our clients
|
|
||||||
this->socket().set_blocking(true);
|
|
||||||
|
|
||||||
if (!this->socket().connect(Core::SocketAddress::local(address))) {
|
|
||||||
perror("connect");
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY(this->socket().is_connected());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void die() override
|
virtual void die() override
|
||||||
|
|
|
@ -6,14 +6,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibCore/System.h>
|
||||||
#include <LibIPC/ClientConnection.h>
|
#include <LibIPC/ClientConnection.h>
|
||||||
|
#include <LibIPC/SystemServerTakeover.h>
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
template<typename ClientConnectionType>
|
template<typename ClientConnectionType>
|
||||||
ErrorOr<NonnullRefPtr<ClientConnectionType>> take_over_accepted_client_from_system_server()
|
ErrorOr<NonnullRefPtr<ClientConnectionType>> take_over_accepted_client_from_system_server()
|
||||||
{
|
{
|
||||||
auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
|
auto socket = TRY(take_over_accepted_socket_from_system_server());
|
||||||
return IPC::new_client_connection<ClientConnectionType>(move(socket));
|
return IPC::new_client_connection<ClientConnectionType>(move(socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
65
Userland/Libraries/LibIPC/SystemServerTakeover.cpp
Normal file
65
Userland/Libraries/LibIPC/SystemServerTakeover.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SystemServerTakeover.h"
|
||||||
|
#include <LibCore/System.h>
|
||||||
|
|
||||||
|
HashMap<String, int> s_overtaken_sockets {};
|
||||||
|
bool s_overtaken_sockets_parsed { false };
|
||||||
|
|
||||||
|
void parse_sockets_from_system_server()
|
||||||
|
{
|
||||||
|
VERIFY(!s_overtaken_sockets_parsed);
|
||||||
|
|
||||||
|
constexpr auto socket_takeover = "SOCKET_TAKEOVER";
|
||||||
|
const char* sockets = getenv(socket_takeover);
|
||||||
|
if (!sockets) {
|
||||||
|
s_overtaken_sockets_parsed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& socket : StringView(sockets).split_view(' ')) {
|
||||||
|
auto params = socket.split_view(':');
|
||||||
|
s_overtaken_sockets.set(params[0].to_string(), strtol(params[1].to_string().characters(), nullptr, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
s_overtaken_sockets_parsed = true;
|
||||||
|
// We wouldn't want our children to think we're passing
|
||||||
|
// them a socket either, so unset the env variable.
|
||||||
|
unsetenv(socket_takeover);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_accepted_socket_from_system_server(String const& socket_path)
|
||||||
|
{
|
||||||
|
if (!s_overtaken_sockets_parsed)
|
||||||
|
parse_sockets_from_system_server();
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
if (socket_path.is_null()) {
|
||||||
|
// We want the first (and only) socket.
|
||||||
|
VERIFY(s_overtaken_sockets.size() == 1);
|
||||||
|
fd = s_overtaken_sockets.begin()->value;
|
||||||
|
} else {
|
||||||
|
auto it = s_overtaken_sockets.find(socket_path);
|
||||||
|
if (it == s_overtaken_sockets.end())
|
||||||
|
return Error::from_string_literal("Non-existent socket requested"sv);
|
||||||
|
fd = it->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check: it has to be a socket.
|
||||||
|
auto stat = TRY(Core::System::fstat(fd));
|
||||||
|
|
||||||
|
if (!S_ISSOCK(stat.st_mode))
|
||||||
|
return Error::from_string_literal("The fd we got from SystemServer is not a socket"sv);
|
||||||
|
|
||||||
|
auto socket = TRY(Core::Stream::LocalSocket::adopt_fd(fd));
|
||||||
|
// It had to be !CLOEXEC for obvious reasons, but we
|
||||||
|
// don't need it to be !CLOEXEC anymore, so set the
|
||||||
|
// CLOEXEC flag now.
|
||||||
|
TRY(socket->set_close_on_exec(true));
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
}
|
12
Userland/Libraries/LibIPC/SystemServerTakeover.h
Normal file
12
Userland/Libraries/LibIPC/SystemServerTakeover.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibCore/Stream.h>
|
||||||
|
|
||||||
|
void parse_sockets_from_system_server();
|
||||||
|
ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_accepted_socket_from_system_server(String const& socket_path = {});
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
namespace ImageDecoderClient {
|
namespace ImageDecoderClient {
|
||||||
|
|
||||||
Client::Client()
|
Client::Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, "/tmp/portal/image")
|
: IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct DecodedImage {
|
||||||
class Client final
|
class Client final
|
||||||
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
||||||
, public ImageDecoderClientEndpoint {
|
, public ImageDecoderClientEndpoint {
|
||||||
C_OBJECT(Client);
|
IPC_CLIENT_CONNECTION(Client, "/tmp/portal/image");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Optional<DecodedImage> decode_image(ReadonlyBytes);
|
Optional<DecodedImage> decode_image(ReadonlyBytes);
|
||||||
|
@ -35,7 +35,7 @@ public:
|
||||||
Function<void()> on_death;
|
Function<void()> on_death;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Client();
|
Client(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
namespace Protocol {
|
namespace Protocol {
|
||||||
|
|
||||||
RequestClient::RequestClient()
|
RequestClient::RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, "/tmp/portal/request")
|
: IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class Request;
|
||||||
class RequestClient final
|
class RequestClient final
|
||||||
: public IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>
|
: public IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>
|
||||||
, public RequestClientEndpoint {
|
, public RequestClientEndpoint {
|
||||||
C_OBJECT(RequestClient);
|
IPC_CLIENT_CONNECTION(RequestClient, "/tmp/portal/request")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename RequestHashMapTraits = Traits<String>>
|
template<typename RequestHashMapTraits = Traits<String>>
|
||||||
|
@ -30,7 +30,7 @@ public:
|
||||||
bool set_certificate(Badge<Request>, Request&, String, String);
|
bool set_certificate(Badge<Request>, Request&, String, String);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RequestClient();
|
RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual void request_progress(i32, Optional<u32> const&, u32) override;
|
virtual void request_progress(i32, Optional<u32> const&, u32) override;
|
||||||
virtual void request_finished(i32, bool, u32) override;
|
virtual void request_finished(i32, bool, u32) override;
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
namespace Protocol {
|
namespace Protocol {
|
||||||
|
|
||||||
WebSocketClient::WebSocketClient()
|
WebSocketClient::WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, "/tmp/portal/websocket")
|
: IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class WebSocket;
|
||||||
class WebSocketClient final
|
class WebSocketClient final
|
||||||
: public IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>
|
: public IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>
|
||||||
, public WebSocketClientEndpoint {
|
, public WebSocketClientEndpoint {
|
||||||
C_OBJECT(WebSocketClient);
|
IPC_CLIENT_CONNECTION(WebSocketClient, "/tmp/portal/websocket")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RefPtr<WebSocket> connect(const URL&, const String& origin = {}, const Vector<String>& protocols = {}, const Vector<String>& extensions = {}, const HashMap<String, String>& request_headers = {});
|
RefPtr<WebSocket> connect(const URL&, const String& origin = {}, const Vector<String>& protocols = {}, const Vector<String>& extensions = {}, const HashMap<String, String>& request_headers = {});
|
||||||
|
@ -29,7 +29,7 @@ public:
|
||||||
bool set_certificate(Badge<WebSocket>, WebSocket&, String, String);
|
bool set_certificate(Badge<WebSocket>, WebSocket&, String, String);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebSocketClient();
|
WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual void connected(i32) override;
|
virtual void connected(i32) override;
|
||||||
virtual void received(i32, bool, ByteBuffer const&) override;
|
virtual void received(i32, bool, ByteBuffer const&) override;
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace SQL {
|
||||||
class SQLClient
|
class SQLClient
|
||||||
: public IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>
|
: public IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>
|
||||||
, public SQLClientEndpoint {
|
, public SQLClientEndpoint {
|
||||||
C_OBJECT(SQLClient);
|
IPC_CLIENT_CONNECTION(SQLClient, "/tmp/portal/sql")
|
||||||
virtual ~SQLClient();
|
virtual ~SQLClient();
|
||||||
|
|
||||||
Function<void(int, String const&)> on_connected;
|
Function<void(int, String const&)> on_connected;
|
||||||
|
@ -27,8 +27,8 @@ class SQLClient
|
||||||
Function<void(int, int)> on_results_exhausted;
|
Function<void(int, int)> on_results_exhausted;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SQLClient()
|
SQLClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, "/tmp/portal/sql")
|
: IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,20 @@ namespace Web::HTML {
|
||||||
|
|
||||||
WebSocketClientManager& WebSocketClientManager::the()
|
WebSocketClientManager& WebSocketClientManager::the()
|
||||||
{
|
{
|
||||||
static WebSocketClientManager* s_the;
|
static RefPtr<WebSocketClientManager> s_the;
|
||||||
if (!s_the)
|
if (!s_the)
|
||||||
s_the = &WebSocketClientManager::construct().leak_ref();
|
s_the = WebSocketClientManager::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
return *s_the;
|
return *s_the;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketClientManager::WebSocketClientManager()
|
ErrorOr<NonnullRefPtr<WebSocketClientManager>> WebSocketClientManager::try_create()
|
||||||
: m_websocket_client(Protocol::WebSocketClient::construct())
|
{
|
||||||
|
auto websocket_client = TRY(Protocol::WebSocketClient::try_create());
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) WebSocketClientManager(move(websocket_client)));
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocketClientManager::WebSocketClientManager(NonnullRefPtr<Protocol::WebSocketClient> websocket_client)
|
||||||
|
: m_websocket_client(move(websocket_client))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,16 @@ class WebSocket;
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
class WebSocketClientManager : public Core::Object {
|
class WebSocketClientManager : public Core::Object {
|
||||||
C_OBJECT(WebSocketClientManager)
|
C_OBJECT_ABSTRACT(WebSocketClientManager)
|
||||||
public:
|
public:
|
||||||
static WebSocketClientManager& the();
|
static WebSocketClientManager& the();
|
||||||
|
|
||||||
RefPtr<Protocol::WebSocket> connect(const AK::URL&);
|
RefPtr<Protocol::WebSocket> connect(const AK::URL&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebSocketClientManager();
|
static ErrorOr<NonnullRefPtr<WebSocketClientManager>> try_create();
|
||||||
|
WebSocketClientManager(NonnullRefPtr<Protocol::WebSocketClient>);
|
||||||
|
|
||||||
RefPtr<Protocol::WebSocketClient> m_websocket_client;
|
RefPtr<Protocol::WebSocketClient> m_websocket_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ ImageDecoderClient::Client& image_decoder_client()
|
||||||
{
|
{
|
||||||
static RefPtr<ImageDecoderClient::Client> image_decoder_client;
|
static RefPtr<ImageDecoderClient::Client> image_decoder_client;
|
||||||
if (!image_decoder_client) {
|
if (!image_decoder_client) {
|
||||||
image_decoder_client = ImageDecoderClient::Client::construct();
|
image_decoder_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
image_decoder_client->on_death = [&] {
|
image_decoder_client->on_death = [&] {
|
||||||
image_decoder_client = nullptr;
|
image_decoder_client = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,14 +21,21 @@ namespace Web {
|
||||||
|
|
||||||
ResourceLoader& ResourceLoader::the()
|
ResourceLoader& ResourceLoader::the()
|
||||||
{
|
{
|
||||||
static ResourceLoader* s_the;
|
static RefPtr<ResourceLoader> s_the;
|
||||||
if (!s_the)
|
if (!s_the)
|
||||||
s_the = &ResourceLoader::construct().leak_ref();
|
s_the = ResourceLoader::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
return *s_the;
|
return *s_the;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLoader::ResourceLoader()
|
ErrorOr<NonnullRefPtr<ResourceLoader>> ResourceLoader::try_create()
|
||||||
: m_protocol_client(Protocol::RequestClient::construct())
|
{
|
||||||
|
|
||||||
|
auto protocol_client = TRY(Protocol::RequestClient::try_create());
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) ResourceLoader(move(protocol_client)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceLoader::ResourceLoader(NonnullRefPtr<Protocol::RequestClient> protocol_client)
|
||||||
|
: m_protocol_client(move(protocol_client))
|
||||||
, m_user_agent(default_user_agent)
|
, m_user_agent(default_user_agent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Web {
|
||||||
constexpr auto default_user_agent = "Mozilla/4.0 (SerenityOS; " CPU_STRING ") LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb";
|
constexpr auto default_user_agent = "Mozilla/4.0 (SerenityOS; " CPU_STRING ") LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb";
|
||||||
|
|
||||||
class ResourceLoader : public Core::Object {
|
class ResourceLoader : public Core::Object {
|
||||||
C_OBJECT(ResourceLoader)
|
C_OBJECT_ABSTRACT(ResourceLoader)
|
||||||
public:
|
public:
|
||||||
static ResourceLoader& the();
|
static ResourceLoader& the();
|
||||||
|
|
||||||
|
@ -52,7 +52,9 @@ public:
|
||||||
void clear_cache();
|
void clear_cache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResourceLoader();
|
ResourceLoader(NonnullRefPtr<Protocol::RequestClient> protocol_client);
|
||||||
|
static ErrorOr<NonnullRefPtr<ResourceLoader>> try_create();
|
||||||
|
|
||||||
static bool is_port_blocked(int port);
|
static bool is_port_blocked(int port);
|
||||||
|
|
||||||
int m_pending_loads { 0 };
|
int m_pending_loads { 0 };
|
||||||
|
|
|
@ -62,7 +62,7 @@ void OutOfProcessWebView::create_client()
|
||||||
{
|
{
|
||||||
m_client_state = {};
|
m_client_state = {};
|
||||||
|
|
||||||
m_client_state.client = WebContentClient::construct(*this);
|
m_client_state.client = WebContentClient::try_create(*this).release_value_but_fixme_should_propagate_errors();
|
||||||
m_client_state.client->on_web_content_process_crash = [this] {
|
m_client_state.client->on_web_content_process_crash = [this] {
|
||||||
deferred_invoke([this] {
|
deferred_invoke([this] {
|
||||||
handle_web_content_process_crash();
|
handle_web_content_process_crash();
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
namespace Web {
|
namespace Web {
|
||||||
|
|
||||||
WebContentClient::WebContentClient(OutOfProcessWebView& view)
|
WebContentClient::WebContentClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, OutOfProcessWebView& view)
|
||||||
: IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>(*this, "/tmp/portal/webcontent")
|
: IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(socket))
|
||||||
, m_view(view)
|
, m_view(view)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@ class OutOfProcessWebView;
|
||||||
class WebContentClient final
|
class WebContentClient final
|
||||||
: public IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>
|
: public IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>
|
||||||
, public WebContentClientEndpoint {
|
, public WebContentClientEndpoint {
|
||||||
C_OBJECT(WebContentClient);
|
IPC_CLIENT_CONNECTION(WebContentClient, "/tmp/portal/webcontent");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Function<void()> on_web_content_process_crash;
|
Function<void()> on_web_content_process_crash;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebContentClient(OutOfProcessWebView&);
|
WebContentClient(NonnullOwnPtr<Core::Stream::LocalSocket>, OutOfProcessWebView&);
|
||||||
|
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ void ClientConnection::for_each(Function<void(ClientConnection&)> callback)
|
||||||
callback(connection);
|
callback(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id, Mixer& mixer)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id, Mixer& mixer)
|
||||||
: IPC::ClientConnection<AudioClientEndpoint, AudioServerEndpoint>(*this, move(client_socket), client_id)
|
: IPC::ClientConnection<AudioClientEndpoint, AudioServerEndpoint>(*this, move(client_socket), client_id)
|
||||||
, m_mixer(mixer)
|
, m_mixer(mixer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
static void for_each(Function<void(ClientConnection&)>);
|
static void for_each(Function<void(ClientConnection&)>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id, Mixer& mixer);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id, Mixer& mixer);
|
||||||
|
|
||||||
virtual Messages::AudioServer::GetMainMixVolumeResponse get_main_mix_volume() override;
|
virtual Messages::AudioServer::GetMainMixVolumeResponse get_main_mix_volume() override;
|
||||||
virtual void set_main_mix_volume(double) override;
|
virtual void set_main_mix_volume(double) override;
|
||||||
|
|
|
@ -25,7 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
||||||
auto server = TRY(Core::LocalServer::try_create());
|
auto server = TRY(Core::LocalServer::try_create());
|
||||||
TRY(server->take_over_from_system_server());
|
TRY(server->take_over_from_system_server());
|
||||||
|
|
||||||
server->on_accept = [&](NonnullRefPtr<Core::LocalSocket> client_socket) {
|
server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> client_socket) {
|
||||||
static int s_next_client_id = 0;
|
static int s_next_client_id = 0;
|
||||||
int client_id = ++s_next_client_id;
|
int client_id = ++s_next_client_id;
|
||||||
(void)IPC::new_client_connection<AudioServer::ClientConnection>(move(client_socket), client_id, *mixer);
|
(void)IPC::new_client_connection<AudioServer::ClientConnection>(move(client_socket), client_id, *mixer);
|
||||||
|
|
|
@ -19,7 +19,7 @@ void ClientConnection::for_each_client(Function<void(ClientConnection&)> callbac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
|
||||||
: IPC::ClientConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket), client_id)
|
: IPC::ClientConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
void notify_about_clipboard_change();
|
void notify_about_clipboard_change();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual Messages::ClipboardServer::GetClipboardDataResponse get_clipboard_data() override;
|
virtual Messages::ClipboardServer::GetClipboardDataResponse get_clipboard_data() override;
|
||||||
virtual void set_clipboard_data(Core::AnonymousBuffer const&, String const&, IPC::Dictionary const&) override;
|
virtual void set_clipboard_data(Core::AnonymousBuffer const&, String const&, IPC::Dictionary const&) override;
|
||||||
|
|
|
@ -74,7 +74,7 @@ static Core::ConfigFile& ensure_domain_config(String const& domain)
|
||||||
return *config;
|
return *config;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
|
||||||
: IPC::ClientConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(client_socket), client_id)
|
: IPC::ClientConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(client_socket), client_id)
|
||||||
, m_sync_timer(Core::Timer::create_single_shot(s_disk_sync_delay_ms, [this]() { sync_dirty_domains_to_disk(); }))
|
, m_sync_timer(Core::Timer::create_single_shot(s_disk_sync_delay_ms, [this]() { sync_dirty_domains_to_disk(); }))
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
bool is_monitoring_domain(String const& domain) const { return m_monitored_domains.contains(domain); }
|
bool is_monitoring_domain(String const& domain) const { return m_monitored_domains.contains(domain); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual void pledge_domains(Vector<String> const&) override;
|
virtual void pledge_domains(Vector<String> const&) override;
|
||||||
virtual void monitor_domain(String const&) override;
|
virtual void monitor_domain(String const&) override;
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace FileSystemAccessServer {
|
||||||
|
|
||||||
static HashMap<int, NonnullRefPtr<ClientConnection>> s_connections;
|
static HashMap<int, NonnullRefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ClientConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket), 1)
|
: IPC::ClientConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket), 1)
|
||||||
{
|
{
|
||||||
s_connections.set(1, *this);
|
s_connections.set(1, *this);
|
||||||
|
@ -72,7 +72,7 @@ void ClientConnection::request_file_handler(i32 window_server_client_id, i32 par
|
||||||
else if (has_flag(requested_access, Core::OpenMode::WriteOnly))
|
else if (has_flag(requested_access, Core::OpenMode::WriteOnly))
|
||||||
access_string = "write to";
|
access_string = "write to";
|
||||||
|
|
||||||
auto pid = this->socket().peer_pid();
|
auto pid = this->socket().peer_pid().release_value_but_fixme_should_propagate_errors();
|
||||||
auto exe_link = LexicalPath("/proc").append(String::number(pid)).append("exe").string();
|
auto exe_link = LexicalPath("/proc").append(String::number(pid)).append("exe").string();
|
||||||
auto exe_path = Core::File::real_path_for(exe_link);
|
auto exe_path = Core::File::real_path_for(exe_link);
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual void request_file_read_only_approved(i32, i32, String const&) override;
|
virtual void request_file_read_only_approved(i32, i32, String const&) override;
|
||||||
virtual void request_file(i32, i32, String const&, Core::OpenMode const&) override;
|
virtual void request_file(i32, i32, String const&, Core::OpenMode const&) override;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
namespace ImageDecoder {
|
namespace ImageDecoder {
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ClientConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket), 1)
|
: IPC::ClientConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket), 1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual Messages::ImageDecoderServer::DecodeImageResponse decode_image(Core::AnonymousBuffer const&) override;
|
virtual Messages::ImageDecoderServer::DecodeImageResponse decode_image(Core::AnonymousBuffer const&) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace InspectorServer {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
|
||||||
: IPC::ClientConnection<InspectorClientEndpoint, InspectorServerEndpoint>(*this, move(socket), client_id)
|
: IPC::ClientConnection<InspectorClientEndpoint, InspectorServerEndpoint>(*this, move(socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual Messages::InspectorServer::GetAllObjectsResponse get_all_objects(pid_t) override;
|
virtual Messages::InspectorServer::GetAllObjectsResponse get_all_objects(pid_t) override;
|
||||||
virtual Messages::InspectorServer::SetInspectedObjectResponse set_inspected_object(pid_t, u64 object_id) override;
|
virtual Messages::InspectorServer::SetInspectedObjectResponse set_inspected_object(pid_t, u64 object_id) override;
|
||||||
|
|
|
@ -16,14 +16,17 @@ InspectableProcess* InspectableProcess::from_pid(pid_t pid)
|
||||||
return g_processes.get(pid).value_or(nullptr);
|
return g_processes.get(pid).value_or(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectableProcess::InspectableProcess(pid_t pid, NonnullRefPtr<Core::LocalSocket> socket)
|
InspectableProcess::InspectableProcess(pid_t pid, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: m_pid(pid)
|
: m_pid(pid)
|
||||||
, m_socket(move(socket))
|
, m_socket(move(socket))
|
||||||
{
|
{
|
||||||
m_socket->set_blocking(true);
|
// FIXME: Propagate errors
|
||||||
|
MUST(m_socket->set_blocking(true));
|
||||||
|
|
||||||
m_socket->on_ready_to_read = [this] {
|
m_socket->on_ready_to_read = [this] {
|
||||||
[[maybe_unused]] auto buffer = m_socket->read(1);
|
char c;
|
||||||
if (m_socket->eof()) {
|
[[maybe_unused]] auto buffer = m_socket->read({ &c, 1 });
|
||||||
|
if (m_socket->is_eof()) {
|
||||||
g_processes.remove(m_pid);
|
g_processes.remove(m_pid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -36,46 +39,51 @@ InspectableProcess::~InspectableProcess()
|
||||||
|
|
||||||
String InspectableProcess::wait_for_response()
|
String InspectableProcess::wait_for_response()
|
||||||
{
|
{
|
||||||
if (m_socket->eof()) {
|
if (m_socket->is_eof()) {
|
||||||
dbgln("InspectableProcess disconnected: PID {}", m_pid);
|
dbgln("InspectableProcess disconnected: PID {}", m_pid);
|
||||||
m_socket->close();
|
m_socket->close();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 length {};
|
u32 length {};
|
||||||
auto nread = m_socket->read((u8*)&length, sizeof(length));
|
auto nread = m_socket->read({ (u8*)&length, sizeof(length) }).release_value_but_fixme_should_propagate_errors();
|
||||||
if (nread != sizeof(length)) {
|
if (nread != sizeof(length)) {
|
||||||
dbgln("InspectableProcess got malformed data: PID {}", m_pid);
|
dbgln("InspectableProcess got malformed data: PID {}", m_pid);
|
||||||
m_socket->close();
|
m_socket->close();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer data;
|
auto data_buffer = ByteBuffer::create_uninitialized(length).release_value();
|
||||||
size_t remaining_bytes = length;
|
auto remaining_data_buffer = data_buffer.bytes();
|
||||||
|
|
||||||
while (remaining_bytes) {
|
while (!remaining_data_buffer.is_empty()) {
|
||||||
auto packet = m_socket->read(remaining_bytes);
|
auto maybe_nread = m_socket->read(remaining_data_buffer);
|
||||||
if (packet.size() == 0)
|
if (maybe_nread.is_error()) {
|
||||||
break;
|
dbgln("InspectableProcess::wait_for_response: Failed to read data: {}", maybe_nread.error());
|
||||||
if (auto result = data.try_append(packet.data(), packet.size()); result.is_error()) {
|
|
||||||
dbgln("Failed to append {} bytes to data buffer: {}", packet.size(), result.error());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
remaining_bytes -= packet.size();
|
|
||||||
|
auto nread = maybe_nread.release_value();
|
||||||
|
if (nread == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
remaining_data_buffer = remaining_data_buffer.slice(nread);
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(data.size() == length);
|
VERIFY(data_buffer.size() == length);
|
||||||
dbgln("Got data size {} and read that many bytes", length);
|
dbgln("Got data size {} and read that many bytes", length);
|
||||||
|
|
||||||
return String::copy(data);
|
return String::copy(data_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectableProcess::send_request(JsonObject const& request)
|
void InspectableProcess::send_request(JsonObject const& request)
|
||||||
{
|
{
|
||||||
auto serialized = request.to_string();
|
auto serialized = request.to_string();
|
||||||
u32 length = serialized.length();
|
u32 length = serialized.length();
|
||||||
m_socket->write((u8 const*)&length, sizeof(length));
|
|
||||||
m_socket->write(serialized);
|
// FIXME: Propagate errors
|
||||||
|
MUST(m_socket->write({ (u8 const*)&length, sizeof(length) }));
|
||||||
|
MUST(m_socket->write(serialized.bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <LibCore/LocalSocket.h>
|
#include <LibCore/Stream.h>
|
||||||
|
|
||||||
namespace InspectorServer {
|
namespace InspectorServer {
|
||||||
|
|
||||||
class InspectableProcess {
|
class InspectableProcess {
|
||||||
public:
|
public:
|
||||||
InspectableProcess(pid_t, NonnullRefPtr<Core::LocalSocket>);
|
InspectableProcess(pid_t, NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
~InspectableProcess();
|
~InspectableProcess();
|
||||||
|
|
||||||
void send_request(JsonObject const& request);
|
void send_request(JsonObject const& request);
|
||||||
|
@ -22,7 +22,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pid_t m_pid { 0 };
|
pid_t m_pid { 0 };
|
||||||
NonnullRefPtr<Core::LocalSocket> m_socket;
|
NonnullOwnPtr<Core::Stream::LocalSocket> m_socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HashMap<pid_t, NonnullOwnPtr<InspectorServer::InspectableProcess>> g_processes;
|
extern HashMap<pid_t, NonnullOwnPtr<InspectorServer::InspectableProcess>> g_processes;
|
||||||
|
|
|
@ -25,7 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
||||||
TRY(inspectables_server->take_over_from_system_server("/tmp/portal/inspectables"));
|
TRY(inspectables_server->take_over_from_system_server("/tmp/portal/inspectables"));
|
||||||
|
|
||||||
inspectables_server->on_accept = [&](auto client_socket) {
|
inspectables_server->on_accept = [&](auto client_socket) {
|
||||||
auto pid = client_socket->peer_pid();
|
auto pid = client_socket->peer_pid().release_value_but_fixme_should_propagate_errors();
|
||||||
InspectorServer::g_processes.set(pid, make<InspectorServer::InspectableProcess>(pid, move(client_socket)));
|
InspectorServer::g_processes.set(pid, make<InspectorServer::InspectableProcess>(pid, move(client_socket)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
namespace LaunchServer {
|
namespace LaunchServer {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
|
||||||
: IPC::ClientConnection<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(client_socket), client_id)
|
: IPC::ClientConnection<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(client_socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual Messages::LaunchServer::OpenUrlResponse open_url(URL const&, String const&) override;
|
virtual Messages::LaunchServer::OpenUrlResponse open_url(URL const&, String const&) override;
|
||||||
virtual Messages::LaunchServer::GetHandlersForUrlResponse get_handlers_for_url(URL const&) override;
|
virtual Messages::LaunchServer::GetHandlersForUrlResponse get_handlers_for_url(URL const&) override;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace LookupServer {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(AK::NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
|
||||||
: IPC::ClientConnection<LookupClientEndpoint, LookupServerEndpoint>(*this, move(socket), client_id)
|
: IPC::ClientConnection<LookupClientEndpoint, LookupServerEndpoint>(*this, move(socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual Messages::LookupServer::LookupNameResponse lookup_name(String const&) override;
|
virtual Messages::LookupServer::LookupNameResponse lookup_name(String const&) override;
|
||||||
virtual Messages::LookupServer::LookupAddressResponse lookup_address(String const&) override;
|
virtual Messages::LookupServer::LookupAddressResponse lookup_address(String const&) override;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace NotificationServer {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
|
||||||
: IPC::ClientConnection<NotificationClientEndpoint, NotificationServerEndpoint>(*this, move(client_socket), client_id)
|
: IPC::ClientConnection<NotificationClientEndpoint, NotificationServerEndpoint>(*this, move(client_socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual void show_notification(String const&, String const&, Gfx::ShareableBitmap const&) override;
|
virtual void show_notification(String const&, String const&, Gfx::ShareableBitmap const&) override;
|
||||||
virtual void close_notification() override;
|
virtual void close_notification() override;
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace RequestServer {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), 1)
|
: IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), 1)
|
||||||
{
|
{
|
||||||
s_connections.set(1, *this);
|
s_connections.set(1, *this);
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
void did_request_certificates(Badge<Request>, Request&);
|
void did_request_certificates(Badge<Request>, Request&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(String const&) override;
|
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(String const&) override;
|
||||||
virtual Messages::RequestServer::StartRequestResponse start_request(String const&, URL const&, IPC::Dictionary const&, ByteBuffer const&) override;
|
virtual Messages::RequestServer::StartRequestResponse start_request(String const&, URL const&, IPC::Dictionary const&, ByteBuffer const&) override;
|
||||||
|
|
|
@ -23,7 +23,7 @@ RefPtr<ClientConnection> ClientConnection::client_connection_for(int client_id)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConnection::ClientConnection(AK::NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
|
||||||
: IPC::ClientConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket), client_id)
|
: IPC::ClientConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
static RefPtr<ClientConnection> client_connection_for(int client_id);
|
static RefPtr<ClientConnection> client_connection_for(int client_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
virtual Messages::SQLServer::ConnectResponse connect(String const&) override;
|
virtual Messages::SQLServer::ConnectResponse connect(String const&) override;
|
||||||
virtual Messages::SQLServer::SqlStatementResponse sql_statement(int, String const&) override;
|
virtual Messages::SQLServer::SqlStatementResponse sql_statement(int, String const&) override;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
class ClipboardServerConnection final
|
class ClipboardServerConnection final
|
||||||
: public IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
: public IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
||||||
, public ClipboardClientEndpoint {
|
, public ClipboardClientEndpoint {
|
||||||
C_OBJECT(ClipboardServerConnection);
|
IPC_CLIENT_CONNECTION(ClipboardServerConnection, "/tmp/portal/clipboard")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Function<void()> on_data_changed;
|
Function<void()> on_data_changed;
|
||||||
|
@ -23,8 +23,8 @@ public:
|
||||||
void set_bitmap(Gfx::Bitmap const& bitmap);
|
void set_bitmap(Gfx::Bitmap const& bitmap);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClipboardServerConnection()
|
ClipboardServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, "/tmp/portal/clipboard")
|
: IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual void clipboard_data_changed(String const&) override
|
virtual void clipboard_data_changed(String const&) override
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
namespace WebContent {
|
namespace WebContent {
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ClientConnection<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(socket), 1)
|
: IPC::ClientConnection<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(socket), 1)
|
||||||
, m_page_host(PageHost::create(*this))
|
, m_page_host(PageHost::create(*this))
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
void initialize_js_console(Badge<PageHost>);
|
void initialize_js_console(Badge<PageHost>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
Web::Page& page();
|
Web::Page& page();
|
||||||
const Web::Page& page() const;
|
const Web::Page& page() const;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace WebSocket {
|
||||||
|
|
||||||
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
static HashMap<int, RefPtr<ClientConnection>> s_connections;
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||||
: IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket), 1)
|
: IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket), 1)
|
||||||
{
|
{
|
||||||
s_connections.set(1, *this);
|
s_connections.set(1, *this);
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||||
|
|
||||||
virtual Messages::WebSocketServer::ConnectResponse connect(URL const&, String const&, Vector<String> const&, Vector<String> const&, IPC::Dictionary const&) override;
|
virtual Messages::WebSocketServer::ConnectResponse connect(URL const&, String const&, Vector<String> const&, Vector<String> const&, IPC::Dictionary const&) override;
|
||||||
virtual Messages::WebSocketServer::ReadyStateResponse ready_state(i32) override;
|
virtual Messages::WebSocketServer::ReadyStateResponse ready_state(i32) override;
|
||||||
|
|
|
@ -45,7 +45,7 @@ ClientConnection* ClientConnection::from_client_id(int client_id)
|
||||||
return (*it).value.ptr();
|
return (*it).value.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id)
|
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
|
||||||
: IPC::ClientConnection<WindowClientEndpoint, WindowServerEndpoint>(*this, move(client_socket), client_id)
|
: IPC::ClientConnection<WindowClientEndpoint, WindowServerEndpoint>(*this, move(client_socket), client_id)
|
||||||
{
|
{
|
||||||
if (!s_connections)
|
if (!s_connections)
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
void notify_display_link(Badge<Compositor>);
|
void notify_display_link(Badge<Compositor>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
|
explicit ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>, int client_id);
|
||||||
|
|
||||||
// ^ClientConnection
|
// ^ClientConnection
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace WindowServer {
|
||||||
|
|
||||||
HashMap<int, NonnullRefPtr<WMClientConnection>> WMClientConnection::s_connections {};
|
HashMap<int, NonnullRefPtr<WMClientConnection>> WMClientConnection::s_connections {};
|
||||||
|
|
||||||
WMClientConnection::WMClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id)
|
WMClientConnection::WMClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id)
|
||||||
: IPC::ClientConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, move(client_socket), client_id)
|
: IPC::ClientConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, move(client_socket), client_id)
|
||||||
{
|
{
|
||||||
s_connections.set(client_id, *this);
|
s_connections.set(client_id, *this);
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
int window_id() const { return m_window_id; }
|
int window_id() const { return m_window_id; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit WMClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id);
|
explicit WMClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> client_socket, int client_id);
|
||||||
|
|
||||||
// ^ClientConnection
|
// ^ClientConnection
|
||||||
virtual void die() override;
|
virtual void die() override;
|
||||||
|
|
|
@ -32,7 +32,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
|
|
||||||
auto audio_client = Audio::ClientConnection::construct();
|
auto audio_client = TRY(Audio::ClientConnection::try_create());
|
||||||
auto maybe_loader = Audio::Loader::create(path);
|
auto maybe_loader = Audio::Loader::create(path);
|
||||||
if (maybe_loader.is_error()) {
|
if (maybe_loader.is_error()) {
|
||||||
warnln("Failed to load audio file: {}", maybe_loader.error().description);
|
warnln("Failed to load audio file: {}", maybe_loader.error().description);
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum AudioVariable : u32 {
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
auto audio_client = Audio::ClientConnection::construct();
|
auto audio_client = TRY(Audio::ClientConnection::try_create());
|
||||||
|
|
||||||
String command = String::empty();
|
String command = String::empty();
|
||||||
Vector<StringView> command_arguments;
|
Vector<StringView> command_arguments;
|
||||||
|
|
|
@ -188,7 +188,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
auto protocol_client = Protocol::RequestClient::construct();
|
auto protocol_client = TRY(Protocol::RequestClient::try_create());
|
||||||
|
|
||||||
auto request = protocol_client->start_request(method, url, request_headers, data ? StringView { data }.bytes() : ReadonlyBytes {});
|
auto request = protocol_client->start_request(method, url, request_headers, data ? StringView { data }.bytes() : ReadonlyBytes {});
|
||||||
if (!request) {
|
if (!request) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
m_editor->set_prompt(prompt_for_level(open_indents));
|
m_editor->set_prompt(prompt_for_level(open_indents));
|
||||||
};
|
};
|
||||||
|
|
||||||
m_sql_client = SQL::SQLClient::construct();
|
m_sql_client = SQL::SQLClient::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
|
|
||||||
m_sql_client->on_connected = [this](int connection_id, String const& connected_to_database) {
|
m_sql_client->on_connected = [this](int connection_id, String const& connected_to_database) {
|
||||||
outln("Connected to \033[33;1m{}\033[0m", connected_to_database);
|
outln("Connected to \033[33;1m{}\033[0m", connected_to_database);
|
||||||
|
|
|
@ -40,9 +40,15 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
|
|
||||||
|
auto maybe_websocket_client = Protocol::WebSocketClient::try_create();
|
||||||
|
if (maybe_websocket_client.is_error()) {
|
||||||
|
warnln("Failed to connect to the websocket server: {}\n", maybe_websocket_client.error());
|
||||||
|
}
|
||||||
|
auto websocket_client = maybe_websocket_client.release_value();
|
||||||
|
|
||||||
RefPtr<Line::Editor> editor = Line::Editor::construct();
|
RefPtr<Line::Editor> editor = Line::Editor::construct();
|
||||||
bool should_quit = false;
|
bool should_quit = false;
|
||||||
auto websocket_client = Protocol::WebSocketClient::construct();
|
|
||||||
auto socket = websocket_client->connect(url, origin);
|
auto socket = websocket_client->connect(url, origin);
|
||||||
if (!socket) {
|
if (!socket) {
|
||||||
warnln("Failed to start socket for '{}'\n", url);
|
warnln("Failed to start socket for '{}'\n", url);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue