summaryrefslogtreecommitdiff
path: root/Userland/DevTools
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2022-01-07 16:28:56 +0200
committerAndreas Kling <kling@serenityos.org>2022-01-12 14:55:19 +0100
commitafb4c447b4e94a70b80209124d71eb0c512be464 (patch)
treedab9359d5b967aea199646a1b254aca758b07586 /Userland/DevTools
parent3afd17db9db6c3ca93c1e402a8007d9b72bf463b (diff)
downloadserenity-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.cpp30
-rw-r--r--Userland/DevTools/HackStudio/TerminalWrapper.h10
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;
};
}