diff --git a/DevTools/HackStudio/Editor.cpp b/DevTools/HackStudio/Editor.cpp index 4a081068e4..7a6972fb08 100644 --- a/DevTools/HackStudio/Editor.cpp +++ b/DevTools/HackStudio/Editor.cpp @@ -48,6 +48,7 @@ #include #include #include +#include // #define EDITOR_DEBUG @@ -480,8 +481,17 @@ void Editor::set_document(GUI::TextDocument& doc) set_syntax_highlighter(nullptr); } - if (m_language_client) - m_language_client->open_file(code_document.file_path().string()); + if (m_language_client) { + auto full_file_path = String::formatted("{}/{}", project().root_directory(), code_document.file_path()); + dbg() << "Opening " << full_file_path; + int fd = open(full_file_path.characters(), O_RDONLY | O_NOCTTY); + if (fd < 0) { + perror("open"); + return; + } + m_language_client->open_file(code_document.file_path().string(), fd); + close(fd); + } } Optional Editor::get_autocomplete_request_data() diff --git a/DevTools/HackStudio/LanguageClient.cpp b/DevTools/HackStudio/LanguageClient.cpp index f394dc674d..462f5b9791 100644 --- a/DevTools/HackStudio/LanguageClient.cpp +++ b/DevTools/HackStudio/LanguageClient.cpp @@ -36,9 +36,9 @@ void ServerConnection::handle(const Messages::LanguageClient::AutoCompleteSugges m_language_client->provide_autocomplete_suggestions(message.suggestions()); } -void LanguageClient::open_file(const String& path) +void LanguageClient::open_file(const String& path, int fd) { - m_connection.post_message(Messages::LanguageServer::FileOpened(path)); + m_connection.post_message(Messages::LanguageServer::FileOpened(path, fd)); } void LanguageClient::set_file_content(const String& path, const String& content) diff --git a/DevTools/HackStudio/LanguageClient.h b/DevTools/HackStudio/LanguageClient.h index 7d0f56d228..bd3298d7a8 100644 --- a/DevTools/HackStudio/LanguageClient.h +++ b/DevTools/HackStudio/LanguageClient.h @@ -43,9 +43,8 @@ class ServerConnection : public IPC::ServerConnection , public LanguageClientEndpoint { public: - ServerConnection(const StringView& socket, const StringView& project_path) + ServerConnection(const StringView& socket) : IPC::ServerConnection(*this, socket) - , m_project_path(project_path) { } @@ -61,7 +60,7 @@ public: virtual void handshake() override { - auto response = send_sync(m_project_path.string()); + auto response = send_sync(); set_my_client_id(response->client_id()); } @@ -73,7 +72,7 @@ public: if (auto instance = s_instances_for_projects.get(key); instance.has_value()) return *instance.value(); - auto connection = ConcreteType::construct(project_path); + auto connection = ConcreteType::construct(); connection->handshake(); s_instances_for_projects.set(key, *connection); return *connection; @@ -83,7 +82,6 @@ protected: virtual void handle(const Messages::LanguageClient::AutoCompleteSuggestions&) override; LanguageClient* m_language_client { nullptr }; - LexicalPath m_project_path; }; class LanguageClient { @@ -100,7 +98,7 @@ public: m_connection.detach(); } - virtual void open_file(const String& path); + virtual void open_file(const String& path, int fd); virtual void set_file_content(const String& path, const String& content); virtual void insert_text(const String& path, const String& text, size_t line, size_t column); virtual void remove_text(const String& path, size_t from_line, size_t from_column, size_t to_line, size_t to_column); diff --git a/DevTools/HackStudio/LanguageClients/ServerConnections.h b/DevTools/HackStudio/LanguageClients/ServerConnections.h index 89266e37ca..bcebdb419e 100644 --- a/DevTools/HackStudio/LanguageClients/ServerConnections.h +++ b/DevTools/HackStudio/LanguageClients/ServerConnections.h @@ -32,16 +32,16 @@ #include #include -#define LANGUAGE_CLIENT(namespace_, socket_name) \ - namespace namespace_ { \ - class ServerConnection : public HackStudio::ServerConnection { \ - C_OBJECT(ServerConnection) \ - private: \ - ServerConnection(const String& project_path) \ - : HackStudio::ServerConnection("/tmp/portal/language/" #socket_name, project_path) \ - { \ - } \ - }; \ +#define LANGUAGE_CLIENT(namespace_, socket_name) \ + namespace namespace_ { \ + class ServerConnection : public HackStudio::ServerConnection { \ + C_OBJECT(ServerConnection) \ + private: \ + ServerConnection() \ + : HackStudio::ServerConnection("/tmp/portal/language/" #socket_name) \ + { \ + } \ + }; \ } namespace LanguageClients { diff --git a/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp b/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp index e43fce6eef..d9dec9bdbb 100644 --- a/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp +++ b/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.cpp @@ -53,12 +53,8 @@ void ClientConnection::die() exit(0); } -OwnPtr ClientConnection::handle(const Messages::LanguageServer::Greet& message) +OwnPtr ClientConnection::handle(const Messages::LanguageServer::Greet&) { - m_project_root = LexicalPath(message.project_root()); -#ifdef DEBUG_CPP_LANGUAGE_SERVER - dbgln("project_root: {}", m_project_root); -#endif return make(client_id()); } @@ -81,16 +77,11 @@ static DefaultDocumentClient s_default_document_client; void ClientConnection::handle(const Messages::LanguageServer::FileOpened& message) { - LexicalPath file_path(String::formatted("{}/{}", m_project_root, message.file_name())); -#ifdef DEBUG_CPP_LANGUAGE_SERVER - dbgln("FileOpened: {}", file_path); -#endif - - auto file = Core::File::construct(file_path.string()); - if (!file->open(Core::IODevice::ReadOnly)) { + auto file = Core::File::construct(this); + if (!file->open(message.file().fd(), Core::IODevice::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes)) { errno = file->error(); perror("open"); - dbgln("Failed to open project file: {}", file_path); + dbgln("Failed to open project file"); return; } auto content = file->read_all(); diff --git a/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h b/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h index 2df3519d92..d0a7b4558c 100644 --- a/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h +++ b/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h @@ -58,7 +58,6 @@ private: RefPtr document_for(const String& file_name); - LexicalPath m_project_root; HashMap> m_open_files; }; diff --git a/DevTools/HackStudio/LanguageServers/Cpp/main.cpp b/DevTools/HackStudio/LanguageServers/Cpp/main.cpp index 9d9ac3ee98..197fd91f27 100644 --- a/DevTools/HackStudio/LanguageServers/Cpp/main.cpp +++ b/DevTools/HackStudio/LanguageServers/Cpp/main.cpp @@ -36,16 +36,20 @@ int main(int, char**) { Core::EventLoop event_loop; - if (pledge("stdio unix rpath", nullptr) < 0) { + if (pledge("stdio unix recvfd", nullptr) < 0) { perror("pledge"); return 1; } auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); IPC::new_client_connection(socket.release_nonnull(), 1); - if (pledge("stdio rpath", nullptr) < 0) { + if (pledge("stdio recvfd", nullptr) < 0) { perror("pledge"); return 1; } + if (unveil(nullptr, nullptr) < 0) { + perror("unveil"); + return 1; + } return event_loop.exec(); } diff --git a/DevTools/HackStudio/LanguageServers/LanguageServer.ipc b/DevTools/HackStudio/LanguageServers/LanguageServer.ipc index 5301c91942..de16fa14ec 100644 --- a/DevTools/HackStudio/LanguageServers/LanguageServer.ipc +++ b/DevTools/HackStudio/LanguageServers/LanguageServer.ipc @@ -1,8 +1,8 @@ endpoint LanguageServer = 8001 { - Greet(String project_root) => (i32 client_id) + Greet() => (i32 client_id) - FileOpened(String file_name) =| + FileOpened(String file_name, IPC::File file) =| FileEditInsertText(String file_name, String text, i32 start_line, i32 start_column) =| FileEditRemoveText(String file_name, i32 start_line, i32 start_column, i32 end_line, i32 end_column) =| SetFileContent(String file_name, String content) =| diff --git a/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp b/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp index 823a36290f..3e32c0d7e9 100644 --- a/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp +++ b/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.cpp @@ -53,12 +53,8 @@ void ClientConnection::die() exit(0); } -OwnPtr ClientConnection::handle(const Messages::LanguageServer::Greet& message) +OwnPtr ClientConnection::handle(const Messages::LanguageServer::Greet&) { - m_project_root = LexicalPath(message.project_root()); -#ifdef DEBUG_SH_LANGUAGE_SERVER - dbgln("project_root: {}", m_project_root); -#endif return make(client_id()); } @@ -81,16 +77,11 @@ static DefaultDocumentClient s_default_document_client; void ClientConnection::handle(const Messages::LanguageServer::FileOpened& message) { - LexicalPath file_path(String::formatted("{}/{}", m_project_root, message.file_name())); -#ifdef DEBUG_SH_LANGUAGE_SERVER - dbgln("FileOpened: {}", file_path); -#endif - - auto file = Core::File::construct(file_path.string()); - if (!file->open(Core::IODevice::ReadOnly)) { + auto file = Core::File::construct(this); + if (!file->open(message.file().fd(), Core::IODevice::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes)) { errno = file->error(); perror("open"); - dbgln("Failed to open project file: {}", file_path); + dbgln("Failed to open project file"); return; } auto content = file->read_all(); diff --git a/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h b/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h index 27f53857b3..bb7fc14bd9 100644 --- a/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h +++ b/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h @@ -59,7 +59,6 @@ private: RefPtr document_for(const String& file_name); - LexicalPath m_project_root; HashMap> m_open_files; AutoComplete m_autocomplete; diff --git a/DevTools/HackStudio/LanguageServers/Shell/main.cpp b/DevTools/HackStudio/LanguageServers/Shell/main.cpp index a5e1417e67..90e3f62271 100644 --- a/DevTools/HackStudio/LanguageServers/Shell/main.cpp +++ b/DevTools/HackStudio/LanguageServers/Shell/main.cpp @@ -36,16 +36,28 @@ int main(int, char**) { Core::EventLoop event_loop; - if (pledge("stdio unix rpath", nullptr) < 0) { + if (pledge("stdio unix rpath recvfd", nullptr) < 0) { perror("pledge"); return 1; } auto socket = Core::LocalSocket::take_over_accepted_socket_from_system_server(); IPC::new_client_connection(socket.release_nonnull(), 1); - if (pledge("stdio rpath", nullptr) < 0) { + if (pledge("stdio rpath recvfd", nullptr) < 0) { perror("pledge"); return 1; } + if (unveil("/etc/passwd", "r") < 0) { + perror("unveil"); + return 1; + } + if (unveil("/", "b") < 0) { + perror("unveil"); + return 1; + } + if (unveil(nullptr, nullptr) < 0) { + perror("unveil"); + return 1; + } return event_loop.exec(); } diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index 7dfab49f7c..7cad913aef 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -59,14 +59,14 @@ static void open_default_project_file(const String& project_path); int main(int argc, char** argv) { - if (pledge("stdio tty accept rpath cpath wpath shared_buffer proc exec unix fattr thread unix", nullptr) < 0) { + if (pledge("stdio tty accept rpath cpath wpath shared_buffer proc exec unix fattr thread unix sendfd", nullptr) < 0) { perror("pledge"); return 1; } auto app = GUI::Application::construct(argc, argv); - if (pledge("stdio tty accept rpath cpath wpath shared_buffer proc exec fattr thread unix", nullptr) < 0) { + if (pledge("stdio tty accept rpath cpath wpath shared_buffer proc exec fattr thread unix sendfd", nullptr) < 0) { perror("pledge"); return 1; }