From dc06ba08026f9b13826c5047bd6ccb6c5312901d Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Wed, 1 Oct 2025 08:18:34 -0600 Subject: [PATCH] Implement process control cpp bindings --- cpp/include/idevice++/process_control.hpp | 41 +++++++++++++ cpp/src/process_control.cpp | 73 +++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 cpp/include/idevice++/process_control.hpp create mode 100644 cpp/src/process_control.cpp diff --git a/cpp/include/idevice++/process_control.hpp b/cpp/include/idevice++/process_control.hpp new file mode 100644 index 0000000..806dcfb --- /dev/null +++ b/cpp/include/idevice++/process_control.hpp @@ -0,0 +1,41 @@ +// Jackson Coxson + +#pragma once +#include +#include +#include +#include + +namespace IdeviceFFI { + +using ProcessControlPtr = + std::unique_ptr>; + +class ProcessControl { + public: + // Factory: borrows the RemoteServer; not consumed + static Result create(RemoteServer& server); + + Result launch_app(std::string bundle_id, + Option> env_vars, + Option> arguments, + bool start_suspended, + bool kill_existing); + Result kill_app(u_int64_t pid); + Result disable_memory_limit(u_int64_t pid); + + ~ProcessControl() noexcept = default; + ProcessControl(ProcessControl&&) noexcept = default; + ProcessControl& operator=(ProcessControl&&) noexcept = default; + ProcessControl(const ProcessControl&) = delete; + ProcessControl& operator=(const ProcessControl&) = delete; + + ProcessControlHandle* raw() const noexcept { return handle_.get(); } + static ProcessControl adopt(ProcessControlHandle* h) noexcept { return ProcessControl(h); } + + private: + explicit ProcessControl(ProcessControlHandle* h) noexcept : handle_(h) {} + ProcessControlPtr handle_{}; +}; + +} // namespace IdeviceFFI diff --git a/cpp/src/process_control.cpp b/cpp/src/process_control.cpp new file mode 100644 index 0000000..2764aac --- /dev/null +++ b/cpp/src/process_control.cpp @@ -0,0 +1,73 @@ +// Jackson Coxson + +#include + +namespace IdeviceFFI { + +Result ProcessControl::create(RemoteServer& server) { + ProcessControlHandle* out = nullptr; + FfiError e(::process_control_new(server.raw(), &out)); + if (e) { + return Err(e); + } + return Ok(ProcessControl::adopt(out)); +} + +Result ProcessControl::launch_app(std::string bundle_id, + Option> env_vars, + Option> arguments, + bool start_suspended, + bool kill_existing) { + std::vector c_env_vars; + size_t env_vars_len = 0; + if (env_vars.is_some()) { + c_env_vars.reserve(env_vars.unwrap().size()); + for (auto& a : env_vars.unwrap()) { + c_env_vars.push_back(a.c_str()); + } + } + + std::vector c_arguments; + size_t arguments_len = 0; + if (arguments.is_some()) { + c_arguments.reserve(arguments.unwrap().size()); + for (auto& a : arguments.unwrap()) { + c_arguments.push_back(a.c_str()); + } + } + + u_int64_t pid = 0; + + FfiError e(::process_control_launch_app( + handle_.get(), + bundle_id.c_str(), + c_env_vars.empty() ? nullptr : const_cast(c_env_vars.data()), + env_vars_len, + c_arguments.empty() ? nullptr : const_cast(c_arguments.data()), + arguments_len, + start_suspended, + kill_existing, + &pid)); + if (e) { + return Err(e); + } + return Ok(pid); +} + +Result ProcessControl::kill_app(u_int64_t pid) { + FfiError e(::process_control_kill_app(handle_.get(), pid)); + if (e) { + return Err(e); + } + return Ok(); +} + +Result ProcessControl::disable_memory_limit(u_int64_t pid) { + FfiError e(::process_control_disable_memory_limit(handle_.get(), pid)); + if (e) { + return Err(e); + } + return Ok(); +} + +} // namespace IdeviceFFI