mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 10:22:05 -05:00
Shell: Handle SIGCHLD after sending SIGCONT to job
This fixes `fg` and `bg` causing the shell to go into an infinite loop of trying to `waitpid` until some current job changes state. a.k.a. "Fix Shell backgrounding, yet again!" :P
This commit is contained in:
parent
50f5959996
commit
5d19509616
3 changed files with 12 additions and 3 deletions
|
@ -111,7 +111,7 @@ int Shell::builtin_bg(int argc, const char** argv)
|
|||
|
||||
job->set_running_in_background(true);
|
||||
job->set_should_announce_exit(true);
|
||||
job->set_is_suspended(false);
|
||||
job->set_shell_did_continue(true);
|
||||
|
||||
dbgln("Resuming {} ({})", job->pid(), job->cmd());
|
||||
warnln("Resuming job {} - {}", job->job_id(), job->cmd().characters());
|
||||
|
@ -396,7 +396,7 @@ int Shell::builtin_fg(int argc, const char** argv)
|
|||
}
|
||||
|
||||
job->set_running_in_background(false);
|
||||
job->set_is_suspended(false);
|
||||
job->set_shell_did_continue(true);
|
||||
|
||||
dbgln("Resuming {} ({})", job->pid(), job->cmd());
|
||||
warnln("Resuming job {} - {}", job->job_id(), job->cmd().characters());
|
||||
|
|
|
@ -86,6 +86,7 @@ public:
|
|||
bool should_announce_exit() const { return m_should_announce_exit; }
|
||||
bool should_announce_signal() const { return m_should_announce_signal; }
|
||||
bool is_suspended() const { return m_is_suspended; }
|
||||
bool shell_did_continue() const { return m_shell_did_continue; }
|
||||
void unblock() const;
|
||||
|
||||
Core::ElapsedTimer& timer() { return m_command_timer; }
|
||||
|
@ -94,6 +95,7 @@ public:
|
|||
void set_signalled(int sig);
|
||||
|
||||
void set_is_suspended(bool value) const { m_is_suspended = value; }
|
||||
void set_shell_did_continue(bool value) const { m_shell_did_continue = value; }
|
||||
|
||||
void set_running_in_background(bool running_in_background)
|
||||
{
|
||||
|
@ -129,6 +131,7 @@ private:
|
|||
Core::ElapsedTimer m_command_timer;
|
||||
mutable bool m_active { true };
|
||||
mutable bool m_is_suspended { false };
|
||||
mutable bool m_shell_did_continue { false };
|
||||
bool m_should_be_disowned { false };
|
||||
OwnPtr<AST::Command> m_command;
|
||||
};
|
||||
|
|
|
@ -1057,7 +1057,7 @@ void Shell::block_on_job(RefPtr<Job> job)
|
|||
if (!job)
|
||||
return;
|
||||
|
||||
if (job->is_suspended())
|
||||
if (job->is_suspended() && !job->shell_did_continue())
|
||||
return; // We cannot wait for a suspended job.
|
||||
|
||||
ScopeGuard io_restorer { [&]() {
|
||||
|
@ -1655,6 +1655,12 @@ void Shell::notify_child_event()
|
|||
}
|
||||
if (child_pid == 0) {
|
||||
// If the child existed, but wasn't dead.
|
||||
if (job.is_suspended() && job.shell_did_continue()) {
|
||||
// The job was suspended, and we sent it a SIGCONT.
|
||||
job.set_is_suspended(false);
|
||||
job.set_shell_did_continue(false);
|
||||
found_child = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (child_pid == job.pid()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue