|
@@ -68,21 +68,23 @@ namespace Shell {
|
|
|
|
|
|
void Shell::setup_signals()
|
|
void Shell::setup_signals()
|
|
{
|
|
{
|
|
- Core::EventLoop::register_signal(SIGCHLD, [this](int) {
|
|
|
|
|
|
+ if (m_should_reinstall_signal_handlers) {
|
|
|
|
+ Core::EventLoop::register_signal(SIGCHLD, [this](int) {
|
|
#ifdef SH_DEBUG
|
|
#ifdef SH_DEBUG
|
|
- dbgln("SIGCHLD!");
|
|
|
|
|
|
+ dbgln("SIGCHLD!");
|
|
#endif
|
|
#endif
|
|
- notify_child_event();
|
|
|
|
- });
|
|
|
|
|
|
+ notify_child_event();
|
|
|
|
+ });
|
|
|
|
|
|
- Core::EventLoop::register_signal(SIGTSTP, [this](auto) {
|
|
|
|
- auto job = current_job();
|
|
|
|
- kill_job(job, SIGTSTP);
|
|
|
|
- if (job) {
|
|
|
|
- job->set_is_suspended(true);
|
|
|
|
- job->unblock();
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
|
|
+ Core::EventLoop::register_signal(SIGTSTP, [this](auto) {
|
|
|
|
+ auto job = current_job();
|
|
|
|
+ kill_job(job, SIGTSTP);
|
|
|
|
+ if (job) {
|
|
|
|
+ job->set_is_suspended(true);
|
|
|
|
+ job->unblock();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void Shell::print_path(const String& path)
|
|
void Shell::print_path(const String& path)
|
|
@@ -484,6 +486,9 @@ bool Shell::invoke_function(const AST::Command& command, int& retval)
|
|
argv.take_first();
|
|
argv.take_first();
|
|
set_local_variable("ARGV", adopt(*new AST::ListValue(move(argv))), true);
|
|
set_local_variable("ARGV", adopt(*new AST::ListValue(move(argv))), true);
|
|
|
|
|
|
|
|
+ Core::EventLoop loop;
|
|
|
|
+ setup_signals();
|
|
|
|
+
|
|
function.body->run(*this);
|
|
function.body->run(*this);
|
|
|
|
|
|
retval = last_return_code;
|
|
retval = last_return_code;
|
|
@@ -670,6 +675,8 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
|
|
return IterationDecision::Continue;
|
|
return IterationDecision::Continue;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ TemporaryChange signal_handler_install { m_should_reinstall_signal_handlers, false };
|
|
|
|
+
|
|
for (auto& redirection : m_global_redirections) {
|
|
for (auto& redirection : m_global_redirections) {
|
|
if (resolve_redirection(redirection) == IterationDecision::Break)
|
|
if (resolve_redirection(redirection) == IterationDecision::Break)
|
|
return nullptr;
|
|
return nullptr;
|
|
@@ -732,6 +739,7 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
|
|
m_is_subshell = true;
|
|
m_is_subshell = true;
|
|
m_pid = getpid();
|
|
m_pid = getpid();
|
|
Core::EventLoop::notify_forked(Core::EventLoop::ForkEvent::Child);
|
|
Core::EventLoop::notify_forked(Core::EventLoop::ForkEvent::Child);
|
|
|
|
+ TemporaryChange signal_handler_install { m_should_reinstall_signal_handlers, true };
|
|
|
|
|
|
if (apply_rewirings() == IterationDecision::Break)
|
|
if (apply_rewirings() == IterationDecision::Break)
|
|
_exit(126);
|
|
_exit(126);
|
|
@@ -756,12 +764,12 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
|
|
if (!m_is_subshell && command.should_wait)
|
|
if (!m_is_subshell && command.should_wait)
|
|
tcsetattr(0, TCSANOW, &default_termios);
|
|
tcsetattr(0, TCSANOW, &default_termios);
|
|
|
|
|
|
- Core::EventLoop mainloop;
|
|
|
|
- setup_signals();
|
|
|
|
-
|
|
|
|
if (command.should_immediately_execute_next) {
|
|
if (command.should_immediately_execute_next) {
|
|
ASSERT(command.argv.is_empty());
|
|
ASSERT(command.argv.is_empty());
|
|
|
|
|
|
|
|
+ Core::EventLoop mainloop;
|
|
|
|
+ setup_signals();
|
|
|
|
+
|
|
for (auto& next_in_chain : command.next_chain)
|
|
for (auto& next_in_chain : command.next_chain)
|
|
run_tail(command, next_in_chain, 0);
|
|
run_tail(command, next_in_chain, 0);
|
|
|
|
|