Serenity Operating System
at master 105 lines 2.4 kB view raw
1/* 2 * Copyright (c) 2020, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include "Job.h" 8#include "AST.h" 9#include "Shell.h" 10#include <inttypes.h> 11#include <stdio.h> 12#include <sys/wait.h> 13 14namespace Shell { 15 16bool Job::print_status(PrintStatusMode mode) 17{ 18 int wstatus; 19 auto rc = waitpid(m_pid, &wstatus, WNOHANG); 20 auto status = "running"; 21 22 if (rc > 0) { 23 if (WIFEXITED(wstatus)) 24 status = "exited"; 25 26 if (WIFSTOPPED(wstatus)) 27 status = "stopped"; 28 29 if (WIFSIGNALED(wstatus)) 30 status = "signaled"; 31 } else { 32 // if rc < 0, We couldn't waitpid() it, probably because we're not the parent shell. 33 // Otherwise, the information we have is already correct, 34 // so just use the old information. 35 if (exited()) 36 status = "exited"; 37 else if (m_is_suspended) 38 status = "stopped"; 39 else if (signaled()) 40 status = "signaled"; 41 } 42 43 char background_indicator = '-'; 44 45 if (is_running_in_background()) 46 background_indicator = '+'; 47 48 const AST::Command& command = *m_command; 49 50 switch (mode) { 51 case PrintStatusMode::Basic: 52 outln("[{}] {} {} {}", m_job_id, background_indicator, status, command); 53 break; 54 case PrintStatusMode::OnlyPID: 55 outln("[{}] {} {} {} {}", m_job_id, background_indicator, m_pid, status, command); 56 break; 57 case PrintStatusMode::ListAll: 58 outln("[{}] {} {} {} {} {}", m_job_id, background_indicator, m_pid, m_pgid, status, command); 59 break; 60 } 61 fflush(stdout); 62 63 return true; 64} 65 66Job::Job(pid_t pid, unsigned pgid, DeprecatedString cmd, u64 job_id, AST::Command&& command) 67 : m_pgid(pgid) 68 , m_pid(pid) 69 , m_job_id(job_id) 70 , m_cmd(move(cmd)) 71{ 72 m_command = make<AST::Command>(move(command)); 73 74 set_running_in_background(false); 75 m_command_timer.start(); 76} 77 78void Job::set_has_exit(int exit_code) 79{ 80 if (m_exited) 81 return; 82 m_exit_code = exit_code; 83 m_exited = true; 84 if (on_exit) 85 on_exit(*this); 86} 87 88void Job::set_signalled(int sig) 89{ 90 if (m_exited) 91 return; 92 m_exited = true; 93 m_exit_code = 126; 94 m_term_sig = sig; 95 if (on_exit) 96 on_exit(*this); 97} 98 99void Job::unblock() 100{ 101 if (!m_exited && on_exit) 102 on_exit(*this); 103} 104 105}