22#include <rclcpp/rclcpp.hpp>
29namespace client_core_components
69 getLogger(),
"[" << this->
getName() <<
"] CpSubprocessExecutor initialized");
89 auto start_time = std::chrono::steady_clock::now();
91 RCLCPP_DEBUG_STREAM(
getLogger(),
"[" << this->
getName() <<
"] Executing: " << command);
94 std::string full_command = command +
" 2>&1";
95 FILE * pipe = popen(full_command.c_str(),
"r");
99 result.
stderr_output =
"Failed to execute command: popen() failed";
106 std::array<char, 4096> buffer;
109 while (fgets(buffer.data(), buffer.size(), pipe) !=
nullptr)
111 output += buffer.data();
116 auto elapsed = std::chrono::steady_clock::now() - start_time;
117 if (std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count() > timeout_ms)
121 result.
stderr_output =
"Command timed out after " + std::to_string(timeout_ms) +
"ms";
129 int status = pclose(pipe);
133 auto end_time = std::chrono::steady_clock::now();
135 std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
138 getLogger(),
"[" << this->
getName() <<
"] Command completed with exit code "
163 std::thread([
this, command, timeout_ms]() { this->
executeCommand(command, timeout_ms); })
172 template <
typename T>
174 void (T::*callback)(
int,
const std::string &), T *
object)
179 template <
typename T>
181 void (T::*callback)(
const std::string &), T *
object)
ISmaccStateMachine * getStateMachine()
virtual std::string getName() const
rclcpp::Logger getLogger() const
smacc2::SmaccSignalConnection createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object)
Generic subprocess execution component for running CLI tools.
virtual ~CpSubprocessExecutor()=default
smacc2::SmaccSignalConnection onCommandFailed(void(T::*callback)(const std::string &), T *object)
std::mutex execution_mutex_
SubprocessResult executeCommand(const std::string &command, int timeout_ms=30000)
Execute a command synchronously.
void executeCommandAsync(const std::string &command, int timeout_ms=30000)
Execute a command asynchronously (fire and forget)
smacc2::SmaccSignal< void(const std::string &error)> onCommandFailed_
void onInitialize() override
smacc2::SmaccSignal< void(int exit_code, const std::string &output)> onCommandCompleted_
smacc2::SmaccSignalConnection onCommandCompleted(void(T::*callback)(int, const std::string &), T *object)
boost::signals2::connection SmaccSignalConnection
Result of a subprocess execution.
std::chrono::milliseconds execution_time
std::string stdout_output
std::string stderr_output