Job.cpp 2.3 KB

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