diff --git a/CMakeLists.txt b/CMakeLists.txt index 34c66654..8ed727e1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ target_link_libraries(Bloom -lstdc++fs) target_link_libraries(Bloom -lpthread) target_link_libraries(Bloom -lusb-1.0) target_link_libraries(Bloom -lhidapi-libusb) +target_link_libraries(Bloom -lprocps) target_link_libraries(Bloom ${YAML_CPP_LIBRARIES}) target_link_libraries(Bloom Qt6::Core) target_link_libraries(Bloom Qt6::Gui) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index df5e0d9f..f4532f7e 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ target_sources( ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/EpollInstance.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/EventFdNotifier.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/ConditionVariableNotifier.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Helpers/Process.cpp ${CMAKE_CURRENT_SOURCE_DIR}/VersionNumber.cpp # Project & application configuration diff --git a/src/Helpers/Process.cpp b/src/Helpers/Process.cpp new file mode 100644 index 00000000..ed068d25 --- /dev/null +++ b/src/Helpers/Process.cpp @@ -0,0 +1,59 @@ +#include "Process.hpp" + +#include +#include + +namespace Bloom +{ + ::pid_t Process::getProcessId() { + return getpid(); + } + + ::pid_t Process::getParentProcessId() { + return getppid(); + } + + bool Process::isProcessManagedByClion(::pid_t processId) { + static auto cachedResult = std::optional(); + + if (cachedResult.has_value()) { + return cachedResult.value(); + } + + // Walk the process tree until we find CLion + while (processId != 0) { + const auto processInfo = Process::getProcessInfo(processId); + + if (!processInfo.has_value()) { + break; + } + + auto* processInfoPtr = processInfo.value(); + + const auto commandLine = std::string(processInfoPtr->cmd); + if (commandLine.find("clion.sh") != std::string::npos) { + freeproc(processInfoPtr); + cachedResult = true; + return true; + } + + processId = processInfoPtr->ppid; + freeproc(processInfoPtr); + } + + cachedResult = true; + return false; + } + + std::optional<::proc_t*> Process::getProcessInfo(::pid_t processId) { + auto* proc = ::openproc(PROC_FILLSTAT | PROC_FILLARG | PROC_PID, &processId); + auto* processInfo = ::readproc(proc, NULL); + + if (processInfo == NULL) { + return std::nullopt; + } + + closeproc(proc); + return processInfo; + } +} diff --git a/src/Helpers/Process.hpp b/src/Helpers/Process.hpp new file mode 100644 index 00000000..bf3b910d --- /dev/null +++ b/src/Helpers/Process.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +namespace Bloom +{ + class Process + { + public: + /** + * Returns the process ID of the current process. + * + * @return + */ + static ::pid_t getProcessId(); + + /** + * Returns the process ID of the current process's parent. + * + * @return + */ + static ::pid_t getParentProcessId(); + + /** + * Returns true if the given process is managed by CLion. + * + * @param processId + * @return + */ + static bool isProcessManagedByClion(::pid_t processId); + + private: + static std::optional<::proc_t*> getProcessInfo(::pid_t processId); + }; +}