diff options
author | Itamar <itamar8910@gmail.com> | 2022-01-07 16:28:56 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-01-12 14:55:19 +0100 |
commit | afb4c447b4e94a70b80209124d71eb0c512be464 (patch) | |
tree | dab9359d5b967aea199646a1b254aca758b07586 /Userland/DevTools | |
parent | 3afd17db9db6c3ca93c1e402a8007d9b72bf463b (diff) | |
download | serenity-afb4c447b4e94a70b80209124d71eb0c512be464.zip |
HackStudio: Add optional parameters to TerminalWrapper::run()
The optional parameters allow specifying a working directory and
controlling whether or not to block until the command returns.
Diffstat (limited to 'Userland/DevTools')
-rw-r--r-- | Userland/DevTools/HackStudio/TerminalWrapper.cpp | 30 | ||||
-rw-r--r-- | Userland/DevTools/HackStudio/TerminalWrapper.h | 10 |
2 files changed, 36 insertions, 4 deletions
diff --git a/Userland/DevTools/HackStudio/TerminalWrapper.cpp b/Userland/DevTools/HackStudio/TerminalWrapper.cpp index 1d1fd6433d..e820c359c5 100644 --- a/Userland/DevTools/HackStudio/TerminalWrapper.cpp +++ b/Userland/DevTools/HackStudio/TerminalWrapper.cpp @@ -7,6 +7,7 @@ #include "TerminalWrapper.h" #include <AK/String.h> #include <LibCore/ConfigFile.h> +#include <LibGUI/Application.h> #include <LibGUI/BoxLayout.h> #include <LibGUI/MessageBox.h> #include <LibVT/TerminalWidget.h> @@ -22,7 +23,7 @@ namespace HackStudio { -void TerminalWrapper::run_command(const String& command) +void TerminalWrapper::run_command(const String& command, Optional<String> working_directory, WaitForExit wait_for_exit) { if (m_pid != -1) { GUI::MessageBox::show(window(), @@ -39,6 +40,8 @@ void TerminalWrapper::run_command(const String& command) } int ptm_fd = ptm_res.value(); + m_child_exited = false; + m_child_exit_status.clear(); m_pid = fork(); if (m_pid < 0) { @@ -46,8 +49,21 @@ void TerminalWrapper::run_command(const String& command) return; } - if (m_pid > 0) + if (m_pid > 0) { + if (wait_for_exit == WaitForExit::Yes) { + GUI::Application::the()->event_loop().spin_until([this]() { + return m_child_exited; + }); + } return; + } + + if (working_directory.has_value()) { + if (chdir(working_directory->characters())) { + perror("chdir"); + exit(1); + } + } if (setup_slave_pseudoterminal(ptm_fd).is_error()) { perror("setup_pseudoterminal"); @@ -93,6 +109,7 @@ ErrorOr<int> TerminalWrapper::setup_master_pseudoterminal(WaitForChildOnExit wai perror("waitpid"); VERIFY_NOT_REACHED(); } + if (WIFEXITED(wstatus)) { m_terminal_widget->inject_string(String::formatted("\033[{};1m(Command exited with code {})\033[0m\r\n", wstatus == 0 ? 32 : 31, WEXITSTATUS(wstatus))); } else if (WIFSTOPPED(wstatus)) { @@ -100,6 +117,9 @@ ErrorOr<int> TerminalWrapper::setup_master_pseudoterminal(WaitForChildOnExit wai } else if (WIFSIGNALED(wstatus)) { m_terminal_widget->inject_string(String::formatted("\033[34;1m(Command signaled with {}!)\033[0m\r\n", strsignal(WTERMSIG(wstatus)))); } + + m_child_exit_status = WEXITSTATUS(wstatus); + m_child_exited = true; } m_pid = -1; @@ -187,4 +207,10 @@ TerminalWrapper::~TerminalWrapper() { } +int TerminalWrapper::child_exit_status() const +{ + VERIFY(m_child_exit_status.has_value()); + return m_child_exit_status.value(); +} + } diff --git a/Userland/DevTools/HackStudio/TerminalWrapper.h b/Userland/DevTools/HackStudio/TerminalWrapper.h index 9918f9335b..a2636fb844 100644 --- a/Userland/DevTools/HackStudio/TerminalWrapper.h +++ b/Userland/DevTools/HackStudio/TerminalWrapper.h @@ -16,8 +16,11 @@ class TerminalWrapper final : public GUI::Widget { C_OBJECT(TerminalWrapper) public: virtual ~TerminalWrapper() override; - - void run_command(const String&); + enum class WaitForExit { + No, + Yes + }; + void run_command(const String&, Optional<String> working_directory = {}, WaitForExit = WaitForExit::No); void kill_running_command(); void clear_including_history(); @@ -30,6 +33,7 @@ public: }; ErrorOr<int> setup_master_pseudoterminal(WaitForChildOnExit = WaitForChildOnExit::Yes); static ErrorOr<void> setup_slave_pseudoterminal(int master_fd); + int child_exit_status() const; Function<void()> on_command_exit; @@ -39,6 +43,8 @@ private: RefPtr<VT::TerminalWidget> m_terminal_widget; pid_t m_pid { -1 }; bool m_user_spawned { true }; + bool m_child_exited { false }; + Optional<int> m_child_exit_status; }; } |