From 143be7234ff0dc45cca2edf683058ae89d823c1e Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sun, 24 May 2020 21:25:01 +0430 Subject: [PATCH] Shell: Kill existing jobs when exiting --- Shell/Shell.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ Shell/Shell.h | 1 + 2 files changed, 41 insertions(+) diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 75f494e4893..61368e31970 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -337,6 +337,7 @@ int Shell::builtin_dirs(int argc, const char** argv) int Shell::builtin_exit(int, const char**) { + stop_all_jobs(); printf("Good-bye!\n"); exit(0); return 0; @@ -1744,5 +1745,44 @@ Shell::Shell() Shell::~Shell() { + stop_all_jobs(); save_history(); } + +void Shell::stop_all_jobs() +{ + if (!jobs.is_empty()) { + printf("Killing active jobs\n"); + for (auto& entry : jobs) { + if (!entry.value->is_running_in_background()) { +#ifdef SH_DEBUG + dbg() << "Job " << entry.value->pid() << " is not running in background"; +#endif + if (killpg(entry.value->pgid(), SIGCONT) < 0) { + perror("killpg(CONT)"); + } + } + + if (killpg(entry.value->pgid(), SIGHUP) < 0) { + perror("killpg(HUP)"); + } + + if (killpg(entry.value->pgid(), SIGTERM) < 0) { + perror("killpg(TERM)"); + } + } + + usleep(10000); // Wait for a bit before killing the job + + for (auto& entry : jobs) { +#ifdef SH_DEBUG + dbg() << "Actively killing " << entry.value->pid() << "(" << entry.value->cmd() << ")"; +#endif + if (killpg(entry.value->pgid(), SIGKILL) < 0) { + if (errno == ESRCH) + continue; // The process has exited all by itself. + perror("killpg(KILL)"); + } + } + } +} diff --git a/Shell/Shell.h b/Shell/Shell.h index 042e5e365be..17a9ad52db5 100644 --- a/Shell/Shell.h +++ b/Shell/Shell.h @@ -162,6 +162,7 @@ private: }; void cache_path(); + void stop_all_jobs(); IterationDecision wait_for_pid(const SpawnedProcess&, bool is_first_command_in_chain, int& return_value);