exit_code.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //
  2. // process/exit_code.hpp
  3. // ~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_PROCESS_V2_EXIT_CODE_HPP
  11. #define BOOST_PROCESS_V2_EXIT_CODE_HPP
  12. #include <boost/process/v2/detail/config.hpp>
  13. #include <boost/process/v2/error.hpp>
  14. #if defined(BOOST_PROCESS_V2_STANDALONE)
  15. #include <asio/associator.hpp>
  16. #include <asio/async_result.hpp>
  17. #else
  18. #include <boost/asio/associator.hpp>
  19. #include <boost/asio/async_result.hpp>
  20. #endif
  21. #if defined(BOOST_PROCESS_V2_POSIX)
  22. #include <sys/wait.h>
  23. #endif
  24. BOOST_PROCESS_V2_BEGIN_NAMESPACE
  25. #if defined(GENERATING_DOCUMENTATION)
  26. /// The native exit-code type, usually an integral value
  27. /** The OS may have a value different from `int` to represent
  28. * the exit codes of subprocesses. It might also
  29. * contain additional information.
  30. */
  31. typedef implementation_defined native_exit_code_type;
  32. /// Check if the native exit code indicates the process is still running
  33. bool process_is_running(native_exit_code_type code);
  34. /// Obtain the portable part of the exit code, i.e. what the subprocess has returned from main.
  35. int evaluate_exit_code(native_exit_code_type code);
  36. #else
  37. #if defined(BOOST_PROCESS_V2_WINDOWS)
  38. typedef unsigned long native_exit_code_type;
  39. namespace detail
  40. {
  41. constexpr native_exit_code_type still_active = 259u;
  42. }
  43. inline bool process_is_running(native_exit_code_type code)
  44. {
  45. return code == detail::still_active;
  46. }
  47. inline int evaluate_exit_code(native_exit_code_type code)
  48. {
  49. return static_cast<int>(code);
  50. }
  51. #else
  52. typedef int native_exit_code_type;
  53. namespace detail
  54. {
  55. constexpr native_exit_code_type still_active = 0x17f;
  56. static_assert(WIFSTOPPED(still_active), "Expected still_active to indicate WIFSTOPPED");
  57. static_assert(!WIFEXITED(still_active), "Expected still_active to not indicate WIFEXITED");
  58. static_assert(!WIFSIGNALED(still_active), "Expected still_active to not indicate WIFSIGNALED");
  59. static_assert(!WIFCONTINUED(still_active), "Expected still_active to not indicate WIFCONTINUED");
  60. }
  61. inline bool process_is_running(int code)
  62. {
  63. return !WIFEXITED(code) && !WIFSIGNALED(code);
  64. }
  65. inline int evaluate_exit_code(int code)
  66. {
  67. if (WIFEXITED(code))
  68. return WEXITSTATUS(code);
  69. else if (WIFSIGNALED(code))
  70. return WTERMSIG(code);
  71. else
  72. return code;
  73. }
  74. #endif
  75. #endif
  76. /// @{
  77. /** Helper to subsume an exit-code into an error_code if there's no actual error isn't set.
  78. * @code {.cpp}
  79. * process proc{ctx, "exit", {"1"}};
  80. *
  81. * proc.async_wait(
  82. * asio::deferred(
  83. * [&proc](error_code ec, int)
  84. * {
  85. * return asio::deferred.values(
  86. * check_exit_code(ec, proc.native_exit_code())
  87. * );
  88. *
  89. * [](error_code ec)
  90. * {
  91. * assert(ec.value() == 10);
  92. * assert(ec.category() == error::get_exit_code_category());
  93. * }));
  94. *
  95. * @endcode
  96. */
  97. inline error_code check_exit_code(
  98. error_code &ec, native_exit_code_type native_code,
  99. const error_category & category = error::get_exit_code_category())
  100. {
  101. if (!ec)
  102. BOOST_PROCESS_V2_ASSIGN_EC(ec, native_code, category);
  103. return ec;
  104. }
  105. /// @}
  106. BOOST_PROCESS_V2_END_NAMESPACE
  107. #endif //BOOST_PROCESS_V2_EXIT_CODE_HPP