| 70 | |
| 71 | |
| 72 | bool CommandExecutor::execute() |
| 73 | { |
| 74 | set_error_msg(""); // clear old error if present |
| 75 | |
| 76 | const bool slot_connected = !(signal_execute_tick().slots().begin() == signal_execute_tick().slots().end()); |
| 77 | |
| 78 | if (slot_connected && !signal_execute_tick().emit(TickStatus::Starting)) |
| 79 | return false; |
| 80 | |
| 81 | if (!cmdex_.execute()) { // try to execute |
| 82 | debug_out_error("app", DBG_FUNC_MSG << "cmdex_.execute() failed.\n"); |
| 83 | import_error(); // get error from cmdex and display warnings if needed |
| 84 | |
| 85 | // emit this for execution loggers |
| 86 | cmdex_sync_signal_execute_finish().emit(CommandExecutorResult(get_command_name(), |
| 87 | get_command_args(), get_stdout_str(), get_stderr_str(), get_error_msg())); |
| 88 | |
| 89 | if (slot_connected) |
| 90 | signal_execute_tick().emit(TickStatus::Failed); |
| 91 | return false; |
| 92 | } |
| 93 | |
| 94 | bool stop_requested = false; // stop requested from tick function |
| 95 | bool signals_sent = false; // stop signals sent |
| 96 | |
| 97 | while(!cmdex_.stopped_cleanup_needed()) { |
| 98 | |
| 99 | if (!stop_requested) { // running and no stop requested yet |
| 100 | // call the tick function with "running" periodically. |
| 101 | // if it returns false, try to stop. |
| 102 | if (slot_connected && !signal_execute_tick().emit(TickStatus::Running)) { |
| 103 | debug_out_info("app", DBG_FUNC_MSG << "execute_tick slot returned false, trying to stop the program.\n"); |
| 104 | stop_requested = true; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | |
| 109 | if (stop_requested && !signals_sent) { // stop request received |
| 110 | // send the stop request to the command |
| 111 | if (!cmdex_.try_stop()) { // try sigterm. this returns false if it can't be done (no permissions, zombie) |
| 112 | debug_out_warn("app", DBG_FUNC_MSG << "cmdex_.try_stop() returned false.\n"); |
| 113 | } |
| 114 | |
| 115 | // set sigkill timeout to 3 sec (in case sigterm fails); won't do anything if already exited. |
| 116 | cmdex_.set_stop_timeouts(std::chrono::milliseconds(0), forced_kill_timeout_msec_); |
| 117 | // import_error(); // don't need errors here - they will be available later anyway. |
| 118 | |
| 119 | signals_sent = true; |
| 120 | } |
| 121 | |
| 122 | |
| 123 | // alert the tick function |
| 124 | if (stop_requested && slot_connected) { |
| 125 | signal_execute_tick().emit(TickStatus::Stopping); // ignore returned value here |
| 126 | } |
| 127 | |
| 128 | |
| 129 | // Without this, no event sources will be processed and the program will |
no test coverage detected