1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 21:57:35 +00:00

Shell: Keep the TTY on the same pgroup to get tty signals

This allows the shell to be notified about SIGWINCH even when a child
process is running in the foreground.
This commit is contained in:
AnotherTest 2020-07-06 20:33:08 +04:30 committed by Andreas Kling
parent 5fedf90bf9
commit 5cdb0ef2e5
4 changed files with 19 additions and 9 deletions

View file

@ -799,7 +799,7 @@ RefPtr<Value> Execute::run(RefPtr<Shell> shell)
} else if (command.should_notify_if_in_background) { } else if (command.should_notify_if_in_background) {
if (job) if (job)
job->set_running_in_background(true); job->set_running_in_background(true);
shell->take_back_stdin(); shell->restore_stdin();
} }
} }
} }

View file

@ -435,8 +435,6 @@ RefPtr<Job> Shell::run_command(AST::Command& command)
return nullptr; return nullptr;
} }
if (child == 0) { if (child == 0) {
setpgid(0, 0);
tcsetpgrp(0, getpid());
tcsetattr(0, TCSANOW, &default_termios); tcsetattr(0, TCSANOW, &default_termios);
for (auto& rewiring : rewirings) { for (auto& rewiring : rewirings) {
#ifdef SH_DEBUG #ifdef SH_DEBUG
@ -511,14 +509,16 @@ bool Shell::run_file(const String& filename, bool explicitly_invoked)
run_command(data); run_command(data);
return true; return true;
} }
void Shell::take_back_stdin() void Shell::restore_stdin()
{ {
tcsetpgrp(0, m_pid);
tcsetattr(0, TCSANOW, &termios); tcsetattr(0, TCSANOW, &termios);
} }
void Shell::block_on_job(RefPtr<Job> job) void Shell::block_on_job(RefPtr<Job> job)
{ {
ScopedValueRollback accepting_signal_rollback(m_is_accepting_signals);
m_is_accepting_signals = false;
if (!job) if (!job)
return; return;
@ -529,13 +529,13 @@ void Shell::block_on_job(RefPtr<Job> job)
loop.quit(0); loop.quit(0);
}; };
if (job->exited()) { if (job->exited()) {
take_back_stdin(); restore_stdin();
return; return;
} }
loop.exec(); loop.exec();
take_back_stdin(); restore_stdin();
} }
String Shell::get_history_path() String Shell::get_history_path()
@ -872,7 +872,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_
bool Shell::read_single_line() bool Shell::read_single_line()
{ {
take_back_stdin(); restore_stdin();
auto line_result = editor->get_line(prompt()); auto line_result = editor->get_line(prompt());
if (line_result.is_error()) { if (line_result.is_error()) {

View file

@ -71,6 +71,8 @@ class Shell : public Core::Object {
public: public:
constexpr static auto init_file_path = "~/shell-init.sh"; constexpr static auto init_file_path = "~/shell-init.sh";
bool is_accepting_signals() const { return m_is_accepting_signals; }
int run_command(const StringView&); int run_command(const StringView&);
RefPtr<Job> run_command(AST::Command&); RefPtr<Job> run_command(AST::Command&);
bool run_file(const String&, bool explicitly_invoked = true); bool run_file(const String&, bool explicitly_invoked = true);
@ -104,7 +106,7 @@ public:
Vector<Line::CompletionSuggestion> complete_user(const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_user(const String&, size_t offset);
Vector<Line::CompletionSuggestion> complete_option(const String&, const String&, size_t offset); Vector<Line::CompletionSuggestion> complete_option(const String&, const String&, size_t offset);
void take_back_stdin(); void restore_stdin();
u64 find_last_job_id() const; u64 find_last_job_id() const;
const Job* find_job(u64 id); const Job* find_job(u64 id);
@ -180,6 +182,7 @@ private:
StringBuilder m_complete_line_builder; StringBuilder m_complete_line_builder;
bool m_should_ignore_jobs_on_next_exit { false }; bool m_should_ignore_jobs_on_next_exit { false };
bool m_is_accepting_signals { true };
pid_t m_pid { 0 }; pid_t m_pid { 0 };
HashMap<String, RefPtr<AST::Value>> m_local_variables; HashMap<String, RefPtr<AST::Value>> m_local_variables;

View file

@ -61,6 +61,8 @@ int main(int argc, char** argv)
Core::EventLoop loop; Core::EventLoop loop;
signal(SIGINT, [](int) { signal(SIGINT, [](int) {
if (!s_shell->is_accepting_signals())
return;
editor->interrupted(); editor->interrupted();
}); });
@ -68,7 +70,12 @@ int main(int argc, char** argv)
editor->resized(); editor->resized();
}); });
signal(SIGTTIN, [](int) {});
signal(SIGTTOU, [](int) {});
signal(SIGHUP, [](int) { signal(SIGHUP, [](int) {
if (!s_shell->is_accepting_signals())
return;
s_shell->save_history(); s_shell->save_history();
}); });