diff --git a/Shell/Builtin.cpp b/Shell/Builtin.cpp index ebc8644a81..5cef22a449 100644 --- a/Shell/Builtin.cpp +++ b/Shell/Builtin.cpp @@ -429,55 +429,17 @@ int Shell::builtin_jobs(int argc, const char** argv) if (!parser.parse(argc, const_cast(argv), false)) return 1; - enum { - Basic, - OnlyPID, - ListAll, - } mode { Basic }; + Job::PrintStatusMode mode = Job::PrintStatusMode::Basic; if (show_pid) - mode = OnlyPID; + mode = Job::PrintStatusMode::OnlyPID; if (list) - mode = ListAll; + mode = Job::PrintStatusMode::ListAll; - for (auto& job : jobs) { - auto pid = job.value->pid(); - int wstatus; - auto rc = waitpid(pid, &wstatus, WNOHANG); - if (rc == -1) { - perror("waitpid"); + for (auto& it : jobs) { + if (!it.value->print_status(mode)) return 1; - } - auto status = "running"; - - if (rc != 0) { - if (WIFEXITED(wstatus)) - status = "exited"; - - if (WIFSTOPPED(wstatus)) - status = "stopped"; - - if (WIFSIGNALED(wstatus)) - status = "signaled"; - } - - char background_indicator = '-'; - - if (job.value->is_running_in_background()) - background_indicator = '+'; - - switch (mode) { - case Basic: - printf("[%" PRIu64 "] %c %s %s\n", job.value->job_id(), background_indicator, status, job.value->cmd().characters()); - break; - case OnlyPID: - printf("[%" PRIu64 "] %c %d %s %s\n", job.value->job_id(), background_indicator, pid, status, job.value->cmd().characters()); - break; - case ListAll: - printf("[%" PRIu64 "] %c %d %d %s %s\n", job.value->job_id(), background_indicator, pid, job.value->pgid(), status, job.value->cmd().characters()); - break; - } } return 0; diff --git a/Shell/CMakeLists.txt b/Shell/CMakeLists.txt index 339f9a48de..10bec5f282 100644 --- a/Shell/CMakeLists.txt +++ b/Shell/CMakeLists.txt @@ -1,9 +1,10 @@ set(SOURCES AST.cpp Builtin.cpp - main.cpp + Job.cpp Parser.cpp Shell.cpp + main.cpp ) serenity_bin(Shell) diff --git a/Shell/Job.cpp b/Shell/Job.cpp new file mode 100644 index 0000000000..29408c5266 --- /dev/null +++ b/Shell/Job.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020, the SerenityOS developers + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Job.h" +#include +#include +#include + +bool Job::print_status(PrintStatusMode mode) +{ + int wstatus; + auto rc = waitpid(m_pid, &wstatus, WNOHANG); + if (rc == -1) { + perror("waitpid"); + return false; + } + auto status = "running"; + + if (rc != 0) { + if (WIFEXITED(wstatus)) + status = "exited"; + + if (WIFSTOPPED(wstatus)) + status = "stopped"; + + if (WIFSIGNALED(wstatus)) + status = "signaled"; + } + + char background_indicator = '-'; + + if (is_running_in_background()) + background_indicator = '+'; + + switch (mode) { + case PrintStatusMode::Basic: + printf("[%" PRIu64 "] %c %s %s\n", m_job_id, background_indicator, status, m_cmd.characters()); + break; + case PrintStatusMode::OnlyPID: + printf("[%" PRIu64 "] %c %d %s %s\n", m_job_id, background_indicator, m_pid, status, m_cmd.characters()); + break; + case PrintStatusMode::ListAll: + printf("[%" PRIu64 "] %c %d %d %s %s\n", m_job_id, background_indicator, m_pid, m_pgid, status, m_cmd.characters()); + break; + } + + return true; +} diff --git a/Shell/Job.h b/Shell/Job.h index 945a4a7afe..75636a8758 100644 --- a/Shell/Job.h +++ b/Shell/Job.h @@ -92,6 +92,14 @@ public: void deactivate() const { m_active = false; } + enum class PrintStatusMode { + Basic, + OnlyPID, + ListAll, + }; + + bool print_status(PrintStatusMode); + private: Job(pid_t pid, unsigned pgid, String cmd, u64 job_id) : m_pgid(pgid)