| 104 | } |
| 105 | |
| 106 | mtf::Result mtf::Process::wait_for_termination(const std::chrono::milliseconds& timeout) |
| 107 | { |
| 108 | Result result; |
| 109 | int status; |
| 110 | |
| 111 | if (!detached) |
| 112 | { |
| 113 | auto tp = std::chrono::steady_clock::now() + timeout; |
| 114 | int rc = -1; |
| 115 | while (true) |
| 116 | { |
| 117 | if ((rc = ::waitpid(pid, &status, WNOHANG)) == pid) |
| 118 | { |
| 119 | if (WIFEXITED(status)) |
| 120 | { |
| 121 | terminated = true; |
| 122 | result.reason = TerminationReason::child_terminated_normally; |
| 123 | result.exit_code = WEXITSTATUS(status); |
| 124 | break; |
| 125 | } |
| 126 | else if (WIFSIGNALED(status)) |
| 127 | { |
| 128 | terminated = true; |
| 129 | result.reason = TerminationReason::child_terminated_by_signal; |
| 130 | result.signal = WTERMSIG(status); |
| 131 | break; |
| 132 | } |
| 133 | else { |
| 134 | terminated = true; |
| 135 | result.reason = TerminationReason::unknown; |
| 136 | break; |
| 137 | } |
| 138 | } |
| 139 | else if (rc == 0) |
| 140 | { |
| 141 | if (std::chrono::steady_clock::now() < tp) |
| 142 | { |
| 143 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); |
| 144 | continue; |
| 145 | } |
| 146 | else |
| 147 | { |
| 148 | BOOST_THROW_EXCEPTION( |
| 149 | ::boost::enable_error_info(std::runtime_error("Timeout while waiting for child to change state")) |
| 150 | << errinfo_pid(pid)); |
| 151 | } |
| 152 | } |
| 153 | else |
| 154 | break; |
| 155 | } |
| 156 | } |
| 157 | return result; |
| 158 | } |
| 159 | |
| 160 | void mtf::Process::kill() |
| 161 | { |
no outgoing calls