LibCore: Make LocalSocket takeover mechanism return ErrorOr<T>

This commit is contained in:
Andreas Kling 2021-11-23 11:14:40 +01:00
parent c37a02341b
commit c1a3968c66
Notes: sideshowbarker 2024-07-18 00:49:18 +09:00
9 changed files with 26 additions and 33 deletions

View file

@ -36,8 +36,8 @@ ErrorOr<int> mode_server()
Core::EventLoop event_loop; Core::EventLoop event_loop;
TRY(Core::System::pledge("stdio unix recvfd rpath ", nullptr)); TRY(Core::System::pledge("stdio unix recvfd rpath ", nullptr));
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
IPC::new_client_connection<LanguageServers::Cpp::ClientConnection>(socket.release_nonnull(), 1); IPC::new_client_connection<LanguageServers::Cpp::ClientConnection>(move(socket), 1);
TRY(Core::System::pledge("stdio recvfd rpath", nullptr)); TRY(Core::System::pledge("stdio recvfd rpath", nullptr));
TRY(Core::System::unveil("/usr/include", "r")); TRY(Core::System::unveil("/usr/include", "r"));

View file

@ -16,8 +16,8 @@ ErrorOr<int> serenity_main(Main::Arguments)
Core::EventLoop event_loop; Core::EventLoop event_loop;
TRY(Core::System::pledge("stdio unix rpath recvfd", nullptr)); TRY(Core::System::pledge("stdio unix rpath recvfd", nullptr));
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
IPC::new_client_connection<LanguageServers::Shell::ClientConnection>(socket.release_nonnull(), 1); IPC::new_client_connection<LanguageServers::Shell::ClientConnection>(move(socket), 1);
TRY(Core::System::pledge("stdio rpath recvfd", nullptr)); TRY(Core::System::pledge("stdio rpath recvfd", nullptr));
TRY(Core::System::unveil("/etc/passwd", "r")); TRY(Core::System::unveil("/etc/passwd", "r"));

View file

@ -5,12 +5,13 @@
*/ */
#include <LibCore/LocalSocket.h> #include <LibCore/LocalSocket.h>
#include <LibCore/System.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h>
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
# include <sys/ucred.h> # include <sys/ucred.h>
#endif #endif
@ -114,7 +115,7 @@ void LocalSocket::parse_sockets_from_system_server()
unsetenv(socket_takeover); unsetenv(socket_takeover);
} }
RefPtr<LocalSocket> LocalSocket::take_over_accepted_socket_from_system_server(String const& socket_path) ErrorOr<NonnullRefPtr<LocalSocket>> LocalSocket::take_over_accepted_socket_from_system_server(String const& socket_path)
{ {
if (!s_overtaken_sockets_parsed) if (!s_overtaken_sockets_parsed)
parse_sockets_from_system_server(); parse_sockets_from_system_server();
@ -126,29 +127,24 @@ RefPtr<LocalSocket> LocalSocket::take_over_accepted_socket_from_system_server(St
fd = s_overtaken_sockets.begin()->value; fd = s_overtaken_sockets.begin()->value;
} else { } else {
auto it = s_overtaken_sockets.find(socket_path); auto it = s_overtaken_sockets.find(socket_path);
if (it == s_overtaken_sockets.end()) { if (it == s_overtaken_sockets.end())
dbgln("Non-existent socket requested"); return Error::from_string_literal("Non-existent socket requested"sv);
return nullptr;
}
fd = it->value; fd = it->value;
} }
// Sanity check: it has to be a socket. // Sanity check: it has to be a socket.
struct stat stat; auto stat = TRY(Core::System::fstat(fd));
int rc = fstat(fd, &stat);
if (rc < 0 || !S_ISSOCK(stat.st_mode)) { if (!S_ISSOCK(stat.st_mode))
if (rc != 0) return Error::from_string_literal("The fd we got from SystemServer is not a socket"sv);
perror("fstat");
dbgln("ERROR: The fd we got from SystemServer is not a socket");
return nullptr;
}
auto socket = LocalSocket::construct(fd); auto socket = LocalSocket::construct(fd);
// It had to be !CLOEXEC for obvious reasons, but we // It had to be !CLOEXEC for obvious reasons, but we
// don't need it to be !CLOEXEC anymore, so set the // don't need it to be !CLOEXEC anymore, so set the
// CLOEXEC flag now. // CLOEXEC flag now.
fcntl(fd, F_SETFD, FD_CLOEXEC); TRY(Core::System::fcntl(fd, F_SETFD, FD_CLOEXEC));
return socket; return socket;
} }

View file

@ -15,7 +15,7 @@ class LocalSocket final : public Socket {
public: public:
virtual ~LocalSocket() override; virtual ~LocalSocket() override;
static RefPtr<LocalSocket> take_over_accepted_socket_from_system_server(String const& socket_path = String()); static ErrorOr<NonnullRefPtr<LocalSocket>> take_over_accepted_socket_from_system_server(String const& socket_path = String());
pid_t peer_pid() const; pid_t peer_pid() const;
private: private:

View file

@ -18,7 +18,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
auto app = GUI::Application::construct(0, nullptr); auto app = GUI::Application::construct(0, nullptr);
app->set_quit_when_last_window_deleted(false); app->set_quit_when_last_window_deleted(false);
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
IPC::new_client_connection<FileSystemAccessServer::ClientConnection>(socket.release_nonnull(), 1); IPC::new_client_connection<FileSystemAccessServer::ClientConnection>(move(socket), 1);
return app->exec(); return app->exec();
} }

View file

@ -17,8 +17,8 @@ ErrorOr<int> serenity_main(Main::Arguments)
TRY(Core::System::pledge("stdio recvfd sendfd unix", nullptr)); TRY(Core::System::pledge("stdio recvfd sendfd unix", nullptr));
TRY(Core::System::unveil(nullptr, nullptr)); TRY(Core::System::unveil(nullptr, nullptr));
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
IPC::new_client_connection<ImageDecoder::ClientConnection>(socket.release_nonnull(), 1); IPC::new_client_connection<ImageDecoder::ClientConnection>(move(socket), 1);
TRY(Core::System::pledge("stdio recvfd sendfd", nullptr)); TRY(Core::System::pledge("stdio recvfd sendfd", nullptr));
return event_loop.exec(); return event_loop.exec();
} }

View file

@ -36,9 +36,8 @@ ErrorOr<int> serenity_main(Main::Arguments)
[[maybe_unused]] auto http = make<RequestServer::HttpProtocol>(); [[maybe_unused]] auto http = make<RequestServer::HttpProtocol>();
[[maybe_unused]] auto https = make<RequestServer::HttpsProtocol>(); [[maybe_unused]] auto https = make<RequestServer::HttpsProtocol>();
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
VERIFY(socket); IPC::new_client_connection<RequestServer::ClientConnection>(move(socket), 1);
IPC::new_client_connection<RequestServer::ClientConnection>(socket.release_nonnull(), 1);
auto result = event_loop.exec(); auto result = event_loop.exec();
// FIXME: We exit instead of returning, so that protocol destructors don't get called. // FIXME: We exit instead of returning, so that protocol destructors don't get called.

View file

@ -21,8 +21,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
TRY(Core::System::unveil("/tmp/portal/websocket", "rw")); TRY(Core::System::unveil("/tmp/portal/websocket", "rw"));
TRY(Core::System::unveil(nullptr, nullptr)); TRY(Core::System::unveil(nullptr, nullptr));
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
VERIFY(socket); IPC::new_client_connection<WebContent::ClientConnection>(move(socket), 1);
IPC::new_client_connection<WebContent::ClientConnection>(socket.release_nonnull(), 1);
return event_loop.exec(); return event_loop.exec();
} }

View file

@ -25,8 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
TRY(Core::System::unveil("/tmp/portal/lookup", "rw")); TRY(Core::System::unveil("/tmp/portal/lookup", "rw"));
TRY(Core::System::unveil(nullptr, nullptr)); TRY(Core::System::unveil(nullptr, nullptr));
auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server());
VERIFY(socket); IPC::new_client_connection<WebSocket::ClientConnection>(move(socket), 1);
IPC::new_client_connection<WebSocket::ClientConnection>(socket.release_nonnull(), 1);
return event_loop.exec(); return event_loop.exec();
} }